保存恢复ListView当前位置:
private void saveCurrentPosition() { if (mListView != null) { int position = mListView.getFirstVisiblePosition(); View v = mListView.getChildAt(0); int top = (v == null) ? 0 : v.getTop(); //保存position和top } } private void restorePosition() { if (mFolder != null && mListView != null) { int position = 0;//取出保存的数据 int top = 0;//取出保存的数据 mListView.setSelectionFromTop(position, top); } }
public static boolean checkChinese(String sequence) { final String format = "[\\u4E00-\\u9FA5\\uF900-\\uFA2D]"; boolean result = false; Pattern pattern = Pattern.compile(format); Matcher matcher = pattern.matcher(sequence); result = matcher.find(); return result; }
解决Android AVD的方向键DPAD不能用的问题
解决方式如下 :
找到C:\Documents and Settings\Administrator\.android\avd\avd2.avd下的config.ini文件。
修改dpad的no为yes重启即可。
Android 结束进程,关闭程序的方法
android.os.Process.killProcess(pid)只能终止本程序的进程,无法终止其它的
在android2.2版本之后则不能再使用restartPackage()方法,而应该使用killBackgroundProcesses()方法
manager.killBackgroundProcesses(getPackageName());
ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
manager.killBackgroundProcesses(getPackageName());
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
还有一种最新发现的方法,利用反射调用forceStopPackage来结束进程
Method forceStopPackage = am.getClass().getDeclaredMethod("forceStopPackage", String.class);
forceStopPackage.setAccessible(true);
forceStopPackage.invoke(am, yourpkgname);
android:sharedUserId="android.uid.system"
<uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"></uses-permission>
因为需要用FORCE_STOP_PACKAGES权限,该权限只赋予系统签名级程序
生成程序性能日志:
性能日志:
if (PROFILE_STARTUP) {
android.os.Debug.startMethodTracing(
Environment.getDataDirectory() + "/debug/log");
}
if (PROFILE_STARTUP) {
android.os.Debug.stopMethodTracing();
}
把launcher.trace文件通过DDMS pull到电脑上,在SDK的tools目录里,执行traceview工具来打开launcher.trace 即可看到内容
通过反射机制获取通知栏高度
public static int getStatusBarHeight(Context context){ Class<?> c = null; Object obj = null; Field field = null; int x = 0, statusBarHeight = 0; try { c = Class.forName("com.android.internal.R$dimen"); obj = c.newInstance(); field = c.getField("status_bar_height"); x = Integer.parseInt(field.get(obj).toString()); statusBarHeight = context.getResources().getDimensionPixelSize(x); } catch (Exception e1) { e1.printStackTrace(); } return statusBarHeight; }
自定义view绘制文本计算文本宽度高度:
private Rect mBounds = new Rect();
String text = String.valueOf(mCount); mPaint.getTextBounds(text, 0, text.length(), mBounds); float textWidth = mBounds.width(); float textHeight = mBounds.height(); canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2 + textHeight / 2, mPaint);
获取异常信息:
public void getInfo(){ String location=""; StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); location = "类名:"+stacks[2].getClassName() + "\n函数名:" + stacks[2].getMethodName() + "\n文件名:" + stacks[2].getFileName() + "\n行号:" + stacks[2].getLineNumber() + ""; System.out.println(location); }
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME_FIRST" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.MONKEY" /> </intent-filter>
android 4.0以后home按键监听方法(观察者模式实现);
/** * Home键监听封装 * * @author way * */ public class HomeWatcher { static final String TAG = "HomeWatcher"; private Context mContext; private IntentFilter mFilter; private OnHomePressedListener mListener; private InnerRecevier mRecevier; // 回调接口 public interface OnHomePressedListener { public void onHomePressed(); public void onHomeLongPressed(); } public HomeWatcher(Context context) { mContext = context; mRecevier = new InnerRecevier(); mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); } /** * 设置监听 * * @param listener */ public void setOnHomePressedListener(OnHomePressedListener listener) { mListener = listener; } /** * 开始监听,注册广播 */ public void startWatch() { if (mRecevier != null) { mContext.registerReceiver(mRecevier, mFilter); } } /** * 停止监听,注销广播 */ public void stopWatch() { if (mRecevier != null) { mContext.unregisterReceiver(mRecevier); } } /** * 广播接收者 */ class InnerRecevier extends BroadcastReceiver { final String SYSTEM_DIALOG_REASON_KEY = "reason"; final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY); if (reason != null) { L.i(TAG, "action:" + action + ",reason:" + reason); if (mListener != null) { if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) { // 短按home键 mListener.onHomePressed(); } else if (reason .equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) { // 长按home键 mListener.onHomeLongPressed(); } } } } } } }
protected void onResume() { // TODO Auto-generated method stub mHomeWatcher = new HomeWatcher(this); mHomeWatcher.setOnHomePressedListener(this); mHomeWatcher.startWatch(); super.onResume(); } protected void onPause() { // TODO Auto-generated method stub super.onPause(); mHomeWatcher.setOnHomePressedListener(null); mHomeWatcher.stopWatch(); }
判断前置摄像,后置摄像是否存在;
/** * 获取前置摄像头 * @return */ @TargetApi(9) private int FindFrontCamera(){ int cameraCount = 0; Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); cameraCount = Camera.getNumberOfCameras(); // get cameras number for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) { Camera.getCameraInfo( camIdx, cameraInfo ); // get camerainfo if ( cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_FRONT ) { // 代表摄像头的方位,目前有定义值两个分别为CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置 return camIdx; } } return -1; } /** * 获取后置摄像头 * @return */ @TargetApi(9) private int FindBackCamera(){ int cameraCount = 0; Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); cameraCount = Camera.getNumberOfCameras(); // get cameras number for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) { Camera.getCameraInfo( camIdx, cameraInfo ); // get camerainfo if ( cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_BACK ) { // 代表摄像头的方位,目前有定义值两个分别为CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置 return camIdx; } } return -1; }
int CammeraIndex=FindBackCamera();
if(CammeraIndex==-1){
CammeraIndex=FindFrontCamera();
}
mServiceCamera = Camera.open(CammeraIndex);
java 线程池简单使用案例:
public class ThreadPool { private AtomicBoolean mStopped = new AtomicBoolean(Boolean.FALSE); private ThreadPoolExecutor mQueue; public ThreadPool() { mQueue = new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), sThreadFactory); mQueue.allowCoreThreadTimeOut(true); } public void start(Runnable run) { mQueue.execute(run); } public void stop() { if (!mStopped.get()) { mQueue.shutdownNow(); mStopped.set(Boolean.TRUE); } } private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { return new Thread(r, "ThreadPool #" + mCount.getAndIncrement()); } }; } protected ExecutorService executorService;// 线程池 private final int POOL_SIZE = 20;// 单个CPU线程池大小 executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE); executorService.execute(client(runnable)); executorService.shutdown(); newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。 newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。 newCachedThreadPool:创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。 newScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。 newSingleThreadExecutor:创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。
android的帮助、about、关于作者、HELP等的提示页面
方法一: AlertDialog ad = new AlertDialog.Builder(SettingPreference.this) .setTitle(R.string.about_dlg_title) .setMessage(R.string.about_dlg_message) .setPositiveButton(getText(R.string.ok), null).create(); ad.show(); //加入链接功能 Linkify.addLinks((TextView) ad.findViewById(android.R.id.message), Linkify.ALL); 方法二: 设计一个AboutDialog类继承于AlertDialog public class AboutDialog extends AlertDialog { public AboutDialog(Context context) { super(context); final View view = getLayoutInflater().inflate(R.layout.about, null); setButton(context.getText(R.string.close), (OnClickListener) null); setIcon(R.drawable.icon_about); setTitle("程序版本 v1.0.0" ); setView(view); } 布局文件about.xml <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_height="fill_parent" android:layout_width="fill_parent" android:text="@string/help_dialog_text" android:padding="6dip" android:textColor="#FFFFFF" /> </ScrollView> </FrameLayout>
webView 实现在线解析文档功能(支持office文档,pdf文档,常见文档,存档文件类型(.ZIP 和 .RAR))
private class HelloWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { String googleDocs = "https://docs.google.com/viewer?url="; if (url.endsWith(".pdf")) { // Load "url" in google docs mWebView.loadUrl(googleDocs + url); } else { // Load all other urls normally. view.loadUrl(url); } return true; } }
//重新配置appliacation <application android:allowBackup="true" android:name="com.pioneersoft.aoc.crashexception.CrashApplication" android:icon="@drawable/icon" android:theme="@android:style/Theme.NoTitleBar" android:label="@string/app_name" > public class CrashApplication extends Application { private PendingIntent restartIntent; @Override public void onCreate() { super.onCreate(); // 以下用来捕获程序崩溃异常 Intent intent = new Intent(); // 参数1:包名,参数2:程序入口的activity intent.setClassName(getPackageName(), "com.pioneersoft.aoc.ui.MainActivity"); restartIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK); Thread.setDefaultUncaughtExceptionHandler(restartHandler); // 程序崩溃时触发线程 } public UncaughtExceptionHandler restartHandler = new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable ex) { AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 5000, restartIntent); // 1秒钟后重启应用 Log.e("crash", "intent restart!"); //退出程序 android.os.Process.killProcess(android.os.Process.myPid()); } };
获取多个可用的存储设备
public static String getExternalStorageDirectory() { //获取所以可用的存储路径 Map<String, String> map = System.getenv(); String[] values = new String[map.values().size()]; map.values().toArray(values); String path = values[values.length - 1]; //获取外置存储卡位置 if (path.startsWith("/mnt/") && !Environment.getExternalStorageDirectory().getAbsolutePath().equals(path)) return path; else return Environment.getExternalStorageDirectory().getAbsolutePath(); }
获取存储可用空间:
private static final double KB = 1024.0; private static final double MB = KB * KB; private static final double GB = KB * KB * KB; private static String showFileSize(double size) { String fileSize; if (size < KB) fileSize = size + "B"; else if (size < MB) fileSize = String.format("%.3f", size / KB) + "KB"; else if (size < GB) fileSize = String.format("%.3f", size / MB) + "MB"; else fileSize = String.format("%.3f", size / GB) + "GB"; return fileSize; } /** 显示SD卡剩余空间 */ public static String getSdcardAvailable() { String result = ""; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { StatFs sf = new StatFs("/mnt/sdcard"); long blockSize = sf.getBlockSize(); long blockCount = sf.getBlockCount(); long availCount = sf.getAvailableBlocks(); return showFileSize(availCount * blockSize) + " \\ " + showFileSize(blockSize * blockCount); } return result; } /** * 获取手机内部可用空间大小 * @return */ static public long getAvailableInternalMemorySize() { File path = Environment.getDataDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSize(); long availableBlocks = stat.getAvailableBlocks(); return availableBlocks * blockSize; } /** * 获取手机内部空间大小 * @return */ static public long getTotalInternalMemorySize() { File path = Environment.getDataDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSize(); long totalBlocks = stat.getBlockCount(); return totalBlocks * blockSize; }
public static String getMemoryUsage() { ActivityManager activityManager = (ActivityManager) DscaApplication.AppContext.getSystemService(Context.ACTIVITY_SERVICE); MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); long availMemory = memoryInfo.availMem / ONE_M_TO_BYTE; long totalMemory = memoryInfo.totalMem / ONE_M_TO_BYTE; return availMemory + "M/" + totalMemory + "M"; }
模拟按键:
public static void simulateKey(final int KeyCode) { new Thread() { @Override public void run() { try { Instrumentation inst = new Instrumentation(); inst.sendKeyDownUpSync(KeyCode); } catch (Exception e) { Log.e("Exception when sendKeyDownUpSync", e.toString()); } } }.start(); } @Override public boolean dispatchKeyEvent(KeyEvent event) { dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis()+100, MotionEvent.ACTION_DOWN, 100, 100, 0)); return super.dispatchKeyEvent(event); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { dispatchKeyEvent(new KeyEvent (KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)); dispatchKeyEvent(new KeyEvent (KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)); dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)); return super.dispatchTouchEvent(ev); }
/**使用Linux shell命令模拟按键信息 * run linuix shell cmmand * @param keyCode */ private void runLinuixShell(final int keyCode){ try{ String keyCommand = "input keyevent " + keyCode; Runtime runtime = Runtime.getRuntime(); Process proc=runtime.exec(keyCommand); Log.e("cmdrun","keycode= "+keyCode); // proc.destroy(); }catch (IOException e){ Log.e("cmderror", e.toString()); } }
// url = file path or whatever suitable URL you want. public static String getMimeType(String url) { String type = null; String extension = MimeTypeMap.getFileExtensionFromUrl(url); if (extension != null) { MimeTypeMap mime = MimeTypeMap.getSingleton(); type = mime.getMimeTypeFromExtension(extension); } return type; }
网络相关判断:
/** * Checks to see if we are connected to a local network, for instance wifi or ethernet * * @return true if connected to a local network */ public static boolean isConnectedToLocalNetwork() { Context context = Globals.getContext(); ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo ni = cm.getActiveNetworkInfo(); // @TODO: this is only defined starting in api level 13 final int TYPE_ETHERNET = 0x00000009; return ni != null && ni.isConnected() == true && (ni.getType() & (ConnectivityManager.TYPE_WIFI | TYPE_ETHERNET)) != 0; } /** * Checks to see if we are connected using wifi * * @return true if connected using wifi */ public static boolean isConnectedUsingWifi() { Context context = Globals.getContext(); ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo ni = cm.getActiveNetworkInfo(); return ni != null && ni.isConnected() == true && ni.getType() == ConnectivityManager.TYPE_WIFI; }
WifiLock wifiLock = null; PowerManager.WakeLock wakeLock; private void takeWakeLock() { if (wakeLock == null) { Log.d(TAG, "About to take wake lock"); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); // Many (all?) devices seem to not properly honor a // PARTIAL_WAKE_LOCK, // which should prevent CPU throttling. This has been // well-complained-about on android-developers. // For these devices, we have a config option to force the phone // into a // full wake lock. if (fullWake) { Log.d(TAG, "Need to take full wake lock"); wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, WAKE_LOCK_TAG); } else { wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG); } wakeLock.setReferenceCounted(false); } Log.d(TAG, "Acquiring wake lock"); wakeLock.acquire(); } private void releaseWakeLock() { Log.d(TAG, "Releasing wake lock"); if (wakeLock != null) { wakeLock.release(); wakeLock = null; Log.d(TAG, "Finished releasing wake lock"); } else { Log.e(TAG, "Couldn't release null wake lock"); } } private void takeWifiLock() { Log.d(TAG, "Taking wifi lock"); if (wifiLock == null) { WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE); wifiLock = manager.createWifiLock("SwiFTP"); wifiLock.setReferenceCounted(false); } wifiLock.acquire(); } private void releaseWifiLock() { Log.d(TAG, "Releasing wifi lock"); if (wifiLock != null) { wifiLock.release(); wifiLock = null; } }
日起比较:
public void compareToNowDate(Date date){ Date nowdate=new Date(); //format date pattern SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //convert to millions seconds long time=DateToLong(StringToDate(formatter.format(nowdate))); long serverTime=DateToLong(date); //convert to seconds long minTime=Math.abs(time-serverTime)/1000; Log.d(getLocalClassName(), "minTime= "+minTime); } private long DateToLong(Date time){ SimpleDateFormat st=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//yyyyMMddHHmmss return Long.parseLong(st.format(time)); } private Date StringToDate(String s){ Date time=null; SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { time=sd.parse(s); } catch (java.text.ParseException e) { System.out.println("输入的日期格式有误!"); e.printStackTrace(); } return time; }