分类归档 终端开发

通过admin

Android获取系统cpu信息,内存,版本,电量等信息

1、CPU频率,CPU信息:/proc/cpuinfo和/proc/stat

通过读取文件/proc/cpuinfo系统CPU的类型等多种信息。

读取/proc/stat 所有CPU活动的信息来计算CPU使用率

 

下面我们就来讲讲如何通过代码来获取CPU频率:

package com.orange.cpu;

 

import java.io.BufferedReader;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

import java.io.InputStream;

 

public class CpuManager {

 

// 获取CPU最大频率(单位KHZ)

// “/system/bin/cat” 命令行

// “/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq” 存储最大频率的文件的路径

public static String getMaxCpuFreq() {

String result = “”;

ProcessBuilder cmd;

try {

String[] args = { “/system/bin/cat”,

“/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq” };

cmd = new ProcessBuilder(args);

Process process = cmd.start();

InputStream in = process.getInputStream();

byte[] re = new byte[24];

while (in.read(re) != -1) {

result = result + new String(re);

}

in.close();

} catch (IOException ex) {

ex.printStackTrace();

result = “N/A”;

}

return result.trim();

}

 

// 获取CPU最小频率(单位KHZ)

public static String getMinCpuFreq() {

String result = “”;

ProcessBuilder cmd;

try {

String[] args = { “/system/bin/cat”,

“/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq” };

cmd = new ProcessBuilder(args);

Process process = cmd.start();

InputStream in = process.getInputStream();

byte[] re = new byte[24];

while (in.read(re) != -1) {

result = result + new String(re);

}

in.close();

} catch (IOException ex) {

ex.printStackTrace();

result = “N/A”;

}

return result.trim();

}

 

// 实时获取CPU当前频率(单位KHZ)

public static String getCurCpuFreq() {

String result = “N/A”;

try {

FileReader fr = new FileReader(

“/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq”);

BufferedReader br = new BufferedReader(fr);

String text = br.readLine();

result = text.trim();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return result;

}

 

// 获取CPU名字

public static String getCpuName() {

try {

FileReader fr = new FileReader(“/proc/cpuinfo”);

BufferedReader br = new BufferedReader(fr);

String text = br.readLine();

String[] array = text.split(“:\\s+”, 2);

for (int i = 0; i < array.length; i++) {

}

return array[1];

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

}

 

2、内存:/proc/meminfo

public void getTotalMemory() {  
        String str1 = "/proc/meminfo";  
        String str2="";  
        try {  
            FileReader fr = new FileReader(str1);  
            BufferedReader localBufferedReader = new BufferedReader(fr, 8192);  
            while ((str2 = localBufferedReader.readLine()) != null) {  
                Log.i(TAG, "---" + str2);  
            }  
        } catch (IOException e) {  
        }  
    }

3、Rom大小

public long[] getRomMemroy() {  
        long[] romInfo = new long[2];  
        //Total rom memory  
        romInfo[0] = getTotalInternalMemorySize();  

        //Available rom memory  
        File path = Environment.getDataDirectory();  
        StatFs stat = new StatFs(path.getPath());  
        long blockSize = stat.getBlockSize();  
        long availableBlocks = stat.getAvailableBlocks();  
        romInfo[1] = blockSize * availableBlocks;  
        getVersion();  
        return romInfo;  
    }  

    public long getTotalInternalMemorySize() {  
        File path = Environment.getDataDirectory();  
        StatFs stat = new StatFs(path.getPath());  
        long blockSize = stat.getBlockSize();  
        long totalBlocks = stat.getBlockCount();  
        return totalBlocks * blockSize;  
    }

4、sdCard大小

public long[] getSDCardMemory() {  
        long[] sdCardInfo=new long[2];  
        String state = Environment.getExternalStorageState();  
        if (Environment.MEDIA_MOUNTED.equals(state)) {  
            File sdcardDir = Environment.getExternalStorageDirectory();  
            StatFs sf = new StatFs(sdcardDir.getPath());  
            long bSize = sf.getBlockSize();  
            long bCount = sf.getBlockCount();  
            long availBlocks = sf.getAvailableBlocks();  

            sdCardInfo[0] = bSize * bCount;//总大小  
            sdCardInfo[1] = bSize * availBlocks;//可用大小  
        }  
        return sdCardInfo;  
    }

5、电池电量

private BroadcastReceiver batteryReceiver=new BroadcastReceiver(){  

        @Override  
        public void onReceive(Context context, Intent intent) {  
            int level = intent.getIntExtra("level", 0);  
            //  level加%就是当前电量了  
    }  
    };  
registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));

6、系统的版本信息

public String[] getVersion(){  
    String[] version={"null","null","null","null"};  
    String str1 = "/proc/version";  
    String str2;  
    String[] arrayOfString;  
    try {  
        FileReader localFileReader = new FileReader(str1);  
        BufferedReader localBufferedReader = new BufferedReader(  
                localFileReader, 8192);  
        str2 = localBufferedReader.readLine();  
        arrayOfString = str2.split("\\s+");  
        version[0]=arrayOfString[2];//KernelVersion  
        localBufferedReader.close();  
    } catch (IOException e) {  
    }  
    version[1] = Build.VERSION.RELEASE;// firmware version  
    version[2]=Build.MODEL;//model  
    version[3]=Build.DISPLAY;//system version  
    return version;  
}

7、mac地址和开机时间

public String[] getOtherInfo(){  
    String[] other={"null","null"};  
       WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);  
       WifiInfo wifiInfo = wifiManager.getConnectionInfo();  
       if(wifiInfo.getMacAddress()!=null){  
        other[0]=wifiInfo.getMacAddress();  
    } else {  
        other[0] = "Fail";  
    }  
    other[1] = getTimes();  
       return other;  
}  
private String getTimes() {  
    long ut = SystemClock.elapsedRealtime() / 1000;  
    if (ut == 0) {  
        ut = 1;  
    }  
    int m = (int) ((ut / 60) % 60);  
    int h = (int) ((ut / 3600));  
    return h + " " + mContext.getString(R.string.info_times_hour) + m + " "  
            + mContext.getString(R.string.info_times_minute);  
}

 

 

部分内容转载自:

http://gqdy365.iteye.com/blog/1066113

http://blog.csdn.net/chuxing/article/details/7571547

通过admin

Android 中使用自定义字体的方法

1、Android系统默认支持三种字体,分别为:“sans”, “serif”, “monospace

2、在Android中可以引入其他字体 。

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:Android="http://schemas.android.com/apk/res/android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent" >

    <TableRow>

        <TextView
            Android:layout_marginRight="4px"
            Android:text="sans:"
            Android:textSize="20sp" >
        </TextView>
        <!-- 使用默认的sans字体 -->

        <TextView
            Android:id="@+id/sans"
            Android:text="Hello,World"
            Android:textSize="20sp"
            Android:typeface="sans" >
        </TextView>
    </TableRow>

    <TableRow>

        <TextView
            Android:layout_marginRight="4px"
            Android:text="serif:"
            Android:textSize="20sp" >
        </TextView>
        <!-- 使用默认的serifs字体 -->

        <TextView
            Android:id="@+id/serif"
            Android:text="Hello,World"
            Android:textSize="20sp"
            Android:typeface="serif" >
        </TextView>
    </TableRow>

    <TableRow>

        <TextView
            Android:layout_marginRight="4px"
            Android:text="monospace:"
            Android:textSize="20sp" >
        </TextView>
        <!-- 使用默认的monospace字体 -->

        <TextView
            Android:id="@+id/monospace"
            Android:text="Hello,World"
            Android:textSize="20sp"
            Android:typeface="monospace" >
        </TextView>
    </TableRow>
    <!-- 这里没有设定字体,我们将在Java代码中设定 -->

    <TableRow>

        <TextView
            Android:layout_marginRight="4px"
            Android:text="custom:"
            Android:textSize="20sp" >
        </TextView>

        <TextView
            Android:id="@+id/custom"
            Android:text="Hello,World"
            Android:textSize="20sp" >
        </TextView>
    </TableRow>

</TableLayout>
// 得到TextView控件对象
TextView textView = (TextView) findViewById(R.id.custom);
// 将字体文件保存在assets/fonts/目录下,www.linuxidc.com创建Typeface对象
Typeface typeFace = Typeface.createFromAsset(getAssets(),"fonts/DroidSansThai.ttf");
// 应用字体
textView.setTypeface(typeFace);

如果想对整个界面的所有控件都应用自定义字体,可以:

package arui.blog.csdn.net;  

import android.app.Activity;  
import android.graphics.Typeface;  
import android.view.View;  
import android.view.ViewGroup;  
import android.widget.Button;  
import android.widget.EditText;  
import android.widget.TextView;  

public class FontManager {  

    public static void changeFonts(ViewGroup root, Activity act) {  

       Typeface tf = Typeface.createFromAsset(act.getAssets(),  
              "fonts/xxx.ttf");  

       for (int i = 0; i < root.getChildCount(); i++) {  
           View v = root.getChildAt(i);  
           if (v instanceof TextView) {  
              ((TextView) v).setTypeface(tf);  
           } else if (v instanceof Button) {  
              ((Button) v).setTypeface(tf);  
           } else if (v instanceof EditText) {  
              ((EditText) v).setTypeface(tf);  
           } else if (v instanceof ViewGroup) {  
              changeFonts((ViewGroup) v, act);  
           }  
       }  

    }  
}

 

通过admin

Android实现多页左右滑动效果,支持子view动态创建和cache

要实现多页滑动效果,主要是需要处理onTouchEvent和onInterceptTouchEvent,要处理好touch事件的子控件和父控件的传递问题。滚动控制可以利用android的Scroller来实现。

对于不清楚android Touch事件的传递过程的,先google一下。

这里提供两种做法:

1、自定义MFlipper控件,从ViewGroup继承,利用Scroller实现滚动,重点是onTouchEvent和onInterceptTouchEvent的重写,要注意什么时候该返回true,什么时候false。否则会导致界面滑动和界面内按钮点击事件相冲突。

由于采用了ViewGroup来管理子view,只适合于页面数较少而且较固定的情况,因为viewgroup需要一开始就调用addView,把所有view都加进去并layout,太多页面会有内存问题。如果是页面很多,而且随时动态增长的话,就需要考虑对view做cache和动态创建,动态layout,具体做法参考下面的方法二;

 

2、从AdapterView继承,参考Android自带ListView的实现,实现子view动态创建和cache,滑动效果等。源码如下:

import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.util.SparseArray;

import android.view.MotionEvent;

import android.view.VelocityTracker;

import android.view.View;

import android.view.ViewConfiguration;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.BaseAdapter;

import android.widget.Gallery;

import android.widget.Scroller;

 

/**

* 自定义一个横向滚动的AdapterView,类似与全屏的Gallery,但是一次只滚动一屏,而且每一屏支持子view的点击处理

* @author weibinke

*

*/

public class MultiPageSwitcher extends AdapterView<BaseAdapter> {

 

private BaseAdapter mAdapter = null;

private Scroller mScroller;

private int mTouchSlop;

private float mTouchStartX;

private float mLastMotionX;

private final static String TAG = “MultiPageSwitcher”;

 

private int mLastScrolledOffset = 0;

 

/** User is not touching the list */

private static final int TOUCH_STATE_RESTING = 0;

 

/** User is scrolling the list */

private static final int TOUCH_STATE_SCROLL = 2;

 

private int mTouchState = TOUCH_STATE_RESTING;

private int mHeightMeasureSpec;

private int mWidthMeasureSpec;

private int mSelectedPosition;

private int mFirstPosition;                                //第一个可见view的position

private int mCurrentSelectedPosition;

 

private VelocityTracker mVelocityTracker;

private static final int SNAP_VELOCITY = 600;

 

protected RecycleBin mRecycler = new RecycleBin();

 

private OnPostionChangeListener mOnPostionChangeListener = null;

 

public MultiPageSwitcher(Context context, AttributeSet attrs) {

super(context, attrs);

mScroller = new Scroller(context);

mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();

}

 

@Override

protected void onLayout(boolean changed, int left, int top, int right,

int bottom) {

// TODO Auto-generated method stub

MLog.d(“MultiPageSwitcher.onlayout start”);

super.onLayout(changed, left, top, right, bottom);

 

if (mAdapter == null) {

return ;

}

 

recycleAllViews();

detachAllViewsFromParent();

mRecycler.clear();

 

fillAllViews();

 

MLog.d(“MultiPageSwitcher.onlayout end”);

}

 

/**

* 从当前可见的view向左边填充

*/

private void fillToGalleryLeft() {

int itemSpacing = 0;

int galleryLeft = 0;

// Set state for initial iteration

View prevIterationView = getChildAt(0);

int curPosition;

int curRightEdge;

if (prevIterationView != null) {

curPosition = mFirstPosition – 1;

curRightEdge = prevIterationView.getLeft() – itemSpacing;

} else {

// No children available!

curPosition = 0;

curRightEdge = getRight() – getLeft();

}

while (curRightEdge > galleryLeft && curPosition >= 0) {

prevIterationView = makeAndAddView(curPosition, curPosition – mSelectedPosition,

curRightEdge, false);

 

// Remember some state

mFirstPosition = curPosition;

// Set state for next iteration

curRightEdge = prevIterationView.getLeft() – itemSpacing;

curPosition–;

}

}

private void fillToGalleryRight() {

int itemSpacing = 0;

int galleryRight = getRight() – getLeft();

int numChildren = getChildCount();

int numItems = mAdapter.getCount();

// Set state for initial iteration

View prevIterationView = getChildAt(numChildren – 1);

int curPosition;

int curLeftEdge;

if (prevIterationView != null) {

curPosition = mFirstPosition + numChildren;

curLeftEdge = prevIterationView.getRight() + itemSpacing;

} else {

mFirstPosition = curPosition = numItems – 1;

curLeftEdge = 0;

}

while (curLeftEdge < galleryRight && curPosition < numItems) {

prevIterationView = makeAndAddView(curPosition, curPosition – mSelectedPosition,

curLeftEdge, true);

 

// Set state for next iteration

curLeftEdge = prevIterationView.getRight() + itemSpacing;

curPosition++;

}

}

 

/**

*填充view

*/

private void fillAllViews(){

//先创建第一个view,使其居中显示

if (mSelectedPosition >= mAdapter.getCount()&& mSelectedPosition > 0) {

//处理被记录被删除导致当前选中位置超出记录数的情况

mSelectedPosition = mAdapter.getCount() – 1;

if(mOnPostionChangeListener != null){

mCurrentSelectedPosition = mSelectedPosition;

mOnPostionChangeListener.onPostionChange(this, mCurrentSelectedPosition);

}

}

 

mFirstPosition = mSelectedPosition;

mCurrentSelectedPosition = mSelectedPosition;

 

View child = makeAndAddView(mSelectedPosition, 0, 0, true);

 

int offset = getWidth() / 2 – (child.getLeft() + child.getWidth() / 2);

child.offsetLeftAndRight(offset);

 

fillToGalleryLeft();

fillToGalleryRight();

 

}

 

/**

* Obtain a view, either by pulling an existing view from the recycler or by

* getting a new one from the adapter. If we are animating, make sure there

* is enough information in the view’s layout parameters to animate from the

* old to new positions.

*

* @param position Position in the gallery for the view to obtain

* @param offset Offset from the selected position

* @param x X-coordintate indicating where this view should be placed. This

*        will either be the left or right edge of the view, depending on

*        the fromLeft paramter

* @param fromLeft Are we posiitoning views based on the left edge? (i.e.,

*        building from left to right)?

* @return A view that has been added to the gallery

*/

private View makeAndAddView(int position, int offset, int x,

boolean fromLeft) {

 

View child;

 

//        child = mRecycler.get(position);

//        if (child != null) {

//            // Position the view

//            setUpChild(child, offset, x, fromLeft);

//

//            return child;

//        }

//

//        // Nothing found in the recycler — ask the adapter for a view

child = mAdapter.getView(position, null, this);

 

// Position the view

setUpChild(child, offset, x, fromLeft);

 

return child;

}

@Override

protected ViewGroup.LayoutParams generateDefaultLayoutParams() {

/*

* Gallery expects Gallery.LayoutParams.

*/

return new Gallery.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,

ViewGroup.LayoutParams.WRAP_CONTENT);

}

 

/**

* Helper for makeAndAddView to set the position of a view and fill out its

* layout paramters.

*

* @param child The view to position

* @param offset Offset from the selected position

* @param x X-coordintate indicating where this view should be placed. This

*        will either be the left or right edge of the view, depending on

*        the fromLeft paramter

* @param fromLeft Are we posiitoning views based on the left edge? (i.e.,

*        building from left to right)?

*/

private void setUpChild(View child, int offset, int x, boolean fromLeft) {

 

// Respect layout params that are already in the view. Otherwise

// make some up…

Gallery.LayoutParams lp = (Gallery.LayoutParams)

child.getLayoutParams();

if (lp == null) {

lp = (Gallery.LayoutParams) generateDefaultLayoutParams();

}

 

addViewInLayout(child, fromLeft ? -1 : 0, lp);

 

child.setSelected(offset == 0);

 

// Get measure specs

int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec,

0, lp.height);

int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,

0, lp.width);

 

// Measure child

child.measure(childWidthSpec, childHeightSpec);

 

int childLeft;

int childRight;

 

// Position vertically based on gravity setting

int childTop = 0;

int childBottom = childTop + child.getMeasuredHeight();

 

int width = child.getMeasuredWidth();

if (fromLeft) {

childLeft = x;

childRight = childLeft + width;

} else {

childLeft = x – width;

childRight = x;

}

 

child.layout(childLeft, childTop, childRight, childBottom);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// TODO Auto-generated method stub

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

mWidthMeasureSpec = widthMeasureSpec;

mHeightMeasureSpec = heightMeasureSpec;

}

 

@Override

public int getCount() {

// TODO Auto-generated method stub

return mAdapter.getCount();

}

 

@Override

public BaseAdapter getAdapter() {

// TODO Auto-generated method stub

return mAdapter;

}

 

@Override

public void setAdapter(BaseAdapter adapter) {

// TODO Auto-generated method stub

mAdapter = adapter;

 

removeAllViewsInLayout();

 

requestLayout();

}

 

@Override

public View getSelectedView() {

// TODO Auto-generated method stub

return null;

}

 

@Override

public void setSelection(int position) {

// TODO Auto-generated method stub

}

 

@Override

public boolean onInterceptTouchEvent(MotionEvent event) {

if (!mScroller.isFinished()) {

return true;

}

 

final int action = event.getAction();

MLog.d(“onInterceptTouchEvent action = “+event.getAction());

 

if (MotionEvent.ACTION_DOWN == action) {

startTouch(event);

 

return false;

}else if (MotionEvent.ACTION_MOVE == action) {

return startScrollIfNeeded(event);

}else if (MotionEvent.ACTION_UP == action || MotionEvent.ACTION_CANCEL == action) {

mTouchState = TOUCH_STATE_RESTING;

 

return false;

}

return false;

}

 

@Override

public boolean onTouchEvent(MotionEvent event) {

 

if (!mScroller.isFinished()) {

return true;

}

 

if (mVelocityTracker == null) {

mVelocityTracker = VelocityTracker.obtain();

}

 

mVelocityTracker.addMovement(event);

 

MLog.d(“onTouchEvent action = “+event.getAction());

final int action = event.getAction();

final float x = event.getX();

 

if (MotionEvent.ACTION_DOWN == action) {

startTouch(event);

 

}else if (MotionEvent.ACTION_MOVE == action) {

if (mTouchState == TOUCH_STATE_RESTING) {

startScrollIfNeeded(event);

}else if (mTouchState == TOUCH_STATE_SCROLL) {

int deltaX = (int)(x – mLastMotionX);

mLastMotionX = x;

 

scrollDeltaX(deltaX);

 

}

}else if (MotionEvent.ACTION_UP == action || MotionEvent.ACTION_CANCEL == action) {

if (mTouchState == TOUCH_STATE_SCROLL) {

onUp(event);

}

}

return true;

}

 

 

private void scrollDeltaX(int deltaX){

 

//先把现有的view坐标移动

for (int i = 0; i < getChildCount(); i++) {

getChildAt(i).offsetLeftAndRight(deltaX);

}

 

boolean toLeft = (deltaX < 0);

detachOffScreenChildren(toLeft);

 

if (deltaX < 0) {

//sroll to right

fillToGalleryRight();

}else {

fillToGalleryLeft();

}

 

invalidate();

 

int position = calculteCenterItem() + mFirstPosition;

if (mCurrentSelectedPosition != position) {

mCurrentSelectedPosition = position;

if (mOnPostionChangeListener != null) {

mOnPostionChangeListener.onPostionChange(this, mCurrentSelectedPosition);

}

}

}

 

private void onUp(MotionEvent event){

 

 

final VelocityTracker velocityTracker = mVelocityTracker;

velocityTracker.computeCurrentVelocity(1000);

int velocityX = (int) velocityTracker.getXVelocity();

 

MLog.d( “onUp velocityX:”+velocityX);

 

if (velocityX < -SNAP_VELOCITY && mSelectedPosition < mAdapter.getCount() – 1) {

if (scrollToChild(mSelectedPosition + 1)) {

mSelectedPosition ++;

}

}else if (velocityX > SNAP_VELOCITY && mSelectedPosition > 0) {

if (scrollToChild(mSelectedPosition – 1)) {

mSelectedPosition –;

}

}else{

int position = calculteCenterItem();

int newpostion = mFirstPosition + position;

if (scrollToChild(newpostion)) {

mSelectedPosition = newpostion;

}

}

 

if (mVelocityTracker != null) {

mVelocityTracker.recycle();

mVelocityTracker = null;

}

 

mTouchState = TOUCH_STATE_RESTING;

}

 

/**

* 计算最接近中心点的view

* @return

*/

private int calculteCenterItem(){

View child = null;

int lastpostion = 0;

int lastclosestDistance = 0;

int viewCenter = getLeft() + getWidth() / 2;

for (int i = 0; i < getChildCount(); i++) {

child = getChildAt(i);

if (child.getLeft() < viewCenter && child.getRight() > viewCenter ) {

lastpostion = i;

break;

}else {

int childClosestDistance = Math.min(Math.abs(child.getLeft() – viewCenter), Math.abs(child.getRight() – viewCenter));

if (childClosestDistance < lastclosestDistance) {

lastclosestDistance = childClosestDistance;

lastpostion = i;

}

}

}

 

return lastpostion;

}

 

public void moveNext(){

if (!mScroller.isFinished()) {

return;

}

 

if (0 <= mSelectedPosition && mSelectedPosition < mAdapter.getCount() – 1) {

if (scrollToChild(mSelectedPosition + 1)) {

mSelectedPosition ++;

}else {

makeAndAddView(mSelectedPosition + 1, 1, getWidth(), true);

if (scrollToChild(mSelectedPosition + 1)) {

mSelectedPosition ++;

}

}

}

}

 

public void movePrevious(){

if (!mScroller.isFinished()) {

return;

}

 

if (0 < mSelectedPosition && mSelectedPosition < mAdapter.getCount()) {

if (scrollToChild(mSelectedPosition -1)) {

mSelectedPosition –;

}else {

makeAndAddView(mSelectedPosition – 1, -1, 0, false);

mFirstPosition = mSelectedPosition – 1;

if (scrollToChild(mSelectedPosition – 1)) {

mSelectedPosition –;

}

}

}

}

 

private boolean scrollToChild(int position){

MLog.d( “scrollToChild positionm,FirstPosition,childcount:”+position + “,” + mFirstPosition+ “,” + getChildCount());

View child = getChildAt(position – mFirstPosition );

if (child != null) {

int distance = getWidth() / 2 – (child.getLeft() + child.getWidth() / 2);

 

mLastScrolledOffset = 0;

mScroller.startScroll(0, 0, distance, 0,200);

invalidate();

 

return true;

}

 

MLog.d( “scrollToChild some error happened”);

 

 

return false;

}

 

@Override

public void computeScroll() {

// TODO Auto-generated method stub

if (mScroller.computeScrollOffset()) {

int scrollX = mScroller.getCurrX();

//                        Mlog.d(“MuticomputeScroll ,” + scrollX);

 

scrollDeltaX(scrollX – mLastScrolledOffset);

mLastScrolledOffset = scrollX;

postInvalidate();

}

}

 

private void startTouch(MotionEvent event){

mTouchStartX = event.getX();

 

mTouchState = mScroller.isFinished()? TOUCH_STATE_RESTING : TOUCH_STATE_SCROLL;

 

mLastMotionX = mTouchStartX;

}

 

private boolean startScrollIfNeeded(MotionEvent event){

final int xPos = (int)event.getX();

mLastMotionX = event.getX();

if (xPos < mTouchStartX – mTouchSlop

|| xPos > mTouchStartX + mTouchSlop

) {

// we’ve moved far enough for this to be a scroll

mTouchState = TOUCH_STATE_SCROLL;

return true;

}

return false;

}

 

/**

* Detaches children that are off the screen (i.e.: Gallery bounds).

*

* @param toLeft Whether to detach children to the left of the Gallery, or

*            to the right.

*/

private void detachOffScreenChildren(boolean toLeft) {

int numChildren = getChildCount();

int start = 0;

int count = 0;

int firstPosition = mFirstPosition;

if (toLeft) {

final int galleryLeft = 0;

for (int i = 0; i < numChildren; i++) {

final View child = getChildAt(i);

if (child.getRight() >= galleryLeft) {

break;

} else {

count++;

mRecycler.put(firstPosition + i, child);

}

}

} else {

final int galleryRight = getWidth();

for (int i = numChildren – 1; i >= 0; i–) {

final View child = getChildAt(i);

if (child.getLeft() <= galleryRight) {

break;

} else {

start = i;

count++;

mRecycler.put(firstPosition + i, child);

}

}

}

 

detachViewsFromParent(start, count);

if (toLeft) {

mFirstPosition += count;

}

mRecycler.clear();

}

public void setOnPositionChangeListen(OnPostionChangeListener onPostionChangeListener){

mOnPostionChangeListener = onPostionChangeListener;

}

public int getCurrentSelectedPosition(){

return mCurrentSelectedPosition;

}

/**

* 刷新数据,本来想用AdapterView.AdapterDataSetObserver机制来实现的,但是整个逻辑移植比较麻烦,就暂时用这个替代了

*/

public void updateData(){

requestLayout();

}

private void recycleAllViews() {

int childCount = getChildCount();

final RecycleBin recycleBin = mRecycler;

 

// All views go in recycler

for (int i=0; i<childCount; i++) {

View v = getChildAt(i);

int index = mFirstPosition + i;

recycleBin.put(index, v);

}

}

class RecycleBin {

private SparseArray<View> mScrapHeap = new SparseArray<View>();

 

public void put(int position, View v) {

if (mScrapHeap.get(position) != null) {

Log.e(TAG,”RecycleBin put error.”);

}

mScrapHeap.put(position, v);

}

View get(int position) {

// System.out.print(“Looking for ” + position);

View result = mScrapHeap.get(position);

if (result != null) {

MLog.d(“RecycleBin get hit.”);

mScrapHeap.delete(position);

} else {

MLog.d(“RecycleBin get Miss.”);

}

return result;

}

View peek(int position) {

// System.out.print(“Looking for ” + position);

return mScrapHeap.get(position);

}

void clear() {

final SparseArray<View> scrapHeap = mScrapHeap;

final int count = scrapHeap.size();

for (int i = 0; i < count; i++) {

final View view = scrapHeap.valueAt(i);

if (view != null) {

removeDetachedView(view, true);

}

}

scrapHeap.clear();

}

}

public interface OnPostionChangeListener{

abstract public void onPostionChange(View v,int position);

}

}

通过admin

Android实现欢迎界面滑动效果

Android应用大部分都会有欢迎界面,几张whatsnew图片可以左右滑动,这里贴下自己的源码。大概思路是:重写Gallery,重写onFling()。

为什么不直接用Gallery呢?因为galler默认会有滑动惯性,会出现一次滑动几页的现象,这里明显不合适。

另外,这种方式会有一个小问题,如果你的界面里带了某些控件,而且设置了OnClickListener(),那么用户如果从控件所在区域开始拖动,是不会有拖动效果的,具体原因是onTouchEvent和onInterceptTouchEvent的传递问题。如果想要解决这个问题,可以看下一篇文章,通过重写AdapterView来实现多页滑动效果。

 

 

贴下代码:

import android.content.Context;

import android.util.AttributeSet;

import android.view.KeyEvent;

import android.view.MotionEvent;

import android.view.ViewConfiguration;

import android.widget.Gallery;

public class SingleScrollGallery extends Gallery {

private static final int TOUCH_STATE_REST = 0;

private static final int TOUCH_STATE_SCROLLING = 1;

private int mTouchState = TOUCH_STATE_REST;

private int mTouchSlop;

private float mLastMotionX;

private float mLastMotionY;

 

public SingleScrollGallery(Context context ,AttributeSet attrSet) {

super(context,attrSet);

// TODO Auto-generated constructor stub

mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();

}

 

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,

float velocityY) {

// TODO Auto-generated method stub

//          return super.onFling(e1, e2, velocityX, velocityY);//方法一:只去除翻页惯性

//  return false;//方法二:只去除翻页惯性  注:没有被注释掉的代码实现了开始说的2种效果。

int kEvent;

if(isScrollingLeft(e1, e2)){

//Check if scrolling left

kEvent = KeyEvent.KEYCODE_DPAD_LEFT;

}  else{

//Otherwise scrolling right

kEvent = KeyEvent.KEYCODE_DPAD_RIGHT;

}

onKeyDown(kEvent, null);

return true;

}

 

private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2)

{

return e2.getX() > e1.getX();

}

 

@Override

public boolean onTouchEvent(MotionEvent event) {

// TODO Auto-generated method stub

return super.onTouchEvent(event);

}

 

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

final int action = ev.getAction();

if ((action == MotionEvent.ACTION_MOVE) &&

(mTouchState != TOUCH_STATE_REST)) {

return true;

}

 

final float x = ev.getX();

final float y = ev.getY();

 

switch (action) {

case MotionEvent.ACTION_MOVE:

final int xDiff = (int)Math.abs(mLastMotionX-x);

if (xDiff>0) {

mTouchState = TOUCH_STATE_SCROLLING;

}

break;

 

case MotionEvent.ACTION_DOWN:

mLastMotionX = x;

mLastMotionY = y;

mTouchState = TOUCH_STATE_REST;

break;

 

case MotionEvent.ACTION_CANCEL:

case MotionEvent.ACTION_UP:

mTouchState = TOUCH_STATE_REST;

break;

}

 

return mTouchState != TOUCH_STATE_REST;

}

}

通过admin

Manifest.xml中不要出现重复的uses-permission声明

虽然Android没有明确指定uses-permission不可以重复写,但是最近的经验是最好是不要重复,否则在某些厂商定制的技巧可能出现问题。

 

最近写一个应用,里面有用到网络访问,发现在有些机型下总是访问不了网络。而其他机型都是可以的。出现问题的手机网络都是正常的。

后面发现Manifest.xml中有好几个网络相关的uses-permission都重复写了几个,于是把重复的去掉之后,发现现在访问网络都正常了。

通过admin

android隐藏以及显示软键盘以及不自动弹出键盘的方法

1、//隐藏软键盘

((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(WidgetSearchActivity.this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

2、//显示软键盘,控件ID可以是EditText,TextView

((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)).showSoftInput(控件ID, 0);

 

3、不自动弹出键盘:

带有EditText控件的在第一次显示的时候会自动获得focus,并弹出键盘,如果不想自动弹出键盘,有两种方法:

方法一:在mainfest文件中把对应的activity设置

android:windowSoftInputMode=”stateHidden” 或者android:windowSoftInputMode=”stateUnchanged”。

方法二:可以在布局中放一个隐藏的TextView,然后在onCreate的时候requsetFocus。

注意TextView不要设置Visiable=gone,否则会失效

,可以在布局中放一个隐藏的TextView,然后在onCreate的时候requsetFocus。

注意TextView不要设置Visiable=gone,否则会失效

<TextView

android:id=”@+id/text_notuse”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:focusable=”true”

android:focusableInTouchMode=”true”

/>

 

TextView textView = (TextView)findViewById(R.id.text_notuse);

textView.requestFocus();

通过admin

微软翻译api的使用介绍和注意事项

google翻译api已经收费了,而微软翻译api目前是免费的,支持几种不同的方式访问,如果感兴趣可以自己封装下协议处理。官方介绍:

http://msdn.microsoft.com/en-us/library/hh454950.aspx

这里介绍一下java下的使用。Java下使用微软翻译api可以直接使用一个开源的sdk,http://code.google.com/p/microsoft-translator-java-api/

 

一、首先去http://code.google.com/p/microsoft-translator-java-api/,下载相关jar文件,这里有对微软翻译api的详细使用有作详细介绍。

二,去申请key,进入http://www.bing.com/developers/createapp.aspx,填写相关的你的应用信息就行了。就会有下面的图片中显示的key,中的Application ID就是key。

三、下面给个实例:

Java代码

收藏代码

      1.   /**
      1. * @Title: MicroTranslate.java
      1. * @Description: TODO(用一句话描述该文件做什么)
      1. * @author zengzhaoshuai
      1. * @date 2012-2-13 下午1:17:07
      1. * @version V1.0
      1. */
      1. import com.memetix.mst.language.Language;
      1. import com.memetix.mst.translate.Translate;
      1. /**
      1.  * @ClassName: MicroTranslate
      1.  * @Description: TODO(这里用一句话描述这个类的作用)
      1.  * @author zengzhaoshuai
      2.  * @date 2012-2-13 下午1:17:07
      1.  *
      1.  */
      1. public class MicroTranslate {
      1.     public static void main(String[] args) throws Exception {
      1.         // Set the Microsoft Translator API Key – Get yours at http://www.bing.com/developers/createapp.aspx
      1.        // Translate.setKey(/* Enter your API Key here */);
      1.         Translate.setKey(“自己申请的key”);
      1.         String translatedText = Translate.execute(“属性”, Language.CHINESE_SIMPLIFIED, Language.ENGLISH);
      1.         System.out.println(translatedText);
      1.     }
      1. }

 

四、运行结果:Property

 

这里说下可能出现的问题:

1、android下要用microsoft-translator-java-api-0.6-jar-with-dependencies.jar,否则运行时可能会报错android java.lang.NoClassDefFoundError: org.json.simple.JSONValue。

2、使用过程中出现错误:TranslateApiException: Cannot find an Azure Market Place Translator Subscription associated with the request credentials,则需要到网址上先订阅translate api的免费流量,操作如下:

Make sure you login to azure market place  click on data and select Microsoft Translator. Now click on 2000000 c/moth @ $0 update option. Now I think this error will go away. Try following link also. This is the link where I signed up for 2000000 c/month offer. I was facing the same problem but when I updated my account through following link, this error went away.(参考:http://social.msdn.microsoft.com/Forums/zh-CN/microsofttranslator/thread/1eeb0066-553f-4523-9a1b-0976e4205bb2)

通过admin

Android 结束进程的方法

对于结束其他的进程可以用killBackgroundProcesses()或者restartPackage,二者都需要指定权限:

<uses-permission android:name=”android.permission.KILL_BACKGROUND_PROCESSES”/>或

<uses-permission android:name=”android.permission.RESTART_PACKAGES”/>,

后者在2.2以后已经废弃;这两个都都无法结束自己的进程。

如果是结束自己的进程可以用android.os.Process.killProcess(android.os.Process.myPid());

注意:如果进程中启动了service或者注册了reciever,已经要先退出,否则会导致进程结束之后自动重启。

 

public void killProcess(String packageName)

{

 

if (packageName.equals(m_context.getApplicationInfo().packageName)) {

android.os.Process.killProcess(android.os.Process.myPid());

}else {

m_am.killBackgroundProcesses(packageName);

}

}

通过admin

尽量不要在android中使用中文路径的问题

在开发过程中发现,有些软件对中文路径支持不大好,如果使用Uri.fromFile转换中文路径为uri的时候,有些软件可能会识别不出来导致功能异常,已知的有两个应用:1、腾讯微博的分享功能;2、酷派D530下调用系统摄像头拍照。

 

如果非要用中文路径,可以采用下面的方式:

String path = getCameraTempFilePath(),;

//有些系统摄像头对中文路径支持不好,通过Uri.fromFile编码之后反而有问题,先手动加上吧

//                 Uri uri = Uri.fromFile(new File(path));

Uri uri = Uri.parse(“file://”+path);

intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

通过admin

解决Eclipse启动不了,一闪而过的问题

今天系统更新,之后就发现Eclipse启动不了了,双击总是一闪而过,google了一下发现下面的解决方法:

 

eclipse启动不了,双击程序后splash一闪而过,没有任何错误提示。怎么办??

这种情况一般是java配置都正确的情况下发生的。错,绝对不是的,即使你修改了都会没有用的。

一般ECLIPSE都是因为JDK升级导致在C:\windoes \system32下生成这三个文件。

(搜到很多打酱油评论都是说重装系统啦,重装eclipse啦。 好点的说改eclipse.ini啦,设置javahome和path啦。。遇到问题就想闪,来点研究的精神好不好。首先总要看看问题出在哪里吧?)

其实不是的,是C:\Windows\System32多了三个文件啦,只要删除这三个文件,再重启一下就行了。不过我很悲崔,我装的ANDROID adt也删除了,不过大家幸运了,以后没有我这么2了。希望这遍文章不要大家走我这种2路。

删除这三个文件ECLIPSE就可以用