android 学习笔记有用代码片段(3)

保存恢复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);  
    }  

launcher 配置:

<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();  
                        }  
                    }  
                }  
            }  
        }  
    }  
}  

在对应Activity中实现OnHomePressedListener 接口并注册监听即可:


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());
        }
    }


得到file的MIME类型:

// 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;
	}
	





你可能感兴趣的:(android,笔记)