1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class CipherUtil {
private final static String[] hexDigits = {"0", "1", "2", "3", "4","5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

public static String generatePassword(String inputString){
return encodeByMD5(inputString);
}

// 判断是否与处理后的加密码匹配
public static boolean validatePassword(String password,String inputString){
if(password.equals(encodeByMD5(inputString)){
return true;
} else {
return false;
}
}

private static String encodeByMD5(String originString){
if (originString != null) {
try{
// 创建指定算法获取信息摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 获取字符串的照耀
byte[] results = md.digest(originString.getBytes());
String resultString = byteArrayToHexString(result);
return resultString.toUpperCase();
} catch(Exception e) {
e.printStackTrace();
}
}
return null;
}

// byte[] -> String
private static String byteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++){
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}

// byte -> String
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n = 256 + n;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
}

  1. 自定义Camera需要添加CAMERA权限

    1
    <uses-permission android:name="android.permission.CAMERA"/>
  2. 通过Camera静态open方法访问摄像头

    1
    Camera camera = Camera.open();

使用完成后调用release方法来释放它

1
camera.release();

  1. 摄像头属性
    通过Camera对象的getParameters方法可以得到Camera.Parameters对象来对摄像头进行设置
    Anroid 2.2引入getFocalLengthget[Horizontal/Vertical]方法分别可以得到焦距和相关水平和垂直视角
    Android 2.3引入getFocusDistances方法,用于估算镜头和当前被对焦的物体之间的距离,该方法并不返回值,而是填充一个与近、远和最佳距离对应的浮点数组,对焦中最清晰的物体位于最佳位置
    1
    2
    3
    4
    5
    6
    7
    float[] focusDistances = new float[3];

    paramerters.getFocusDistance(focusDistance);

    float near = focusDistances[Camera.Parameters.FOCUS_DISTANCE_NEAR_INDEX];
    float far = focusDistance[Camera.Parameters.FOCUS_DISTANCE_FAR_INDEX];
    float optimal = focusDistance[Camera.Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX];

通过使用set*方法来修改Parameters参数

  • [get/set]SceneMode 使用一个SCENE_MODE_*的常量设置所拍摄场景的类型。
  • [get/set]FlashMode 使用一个FLASH_MODE_*常量设置闪光模式(通常为“打开”、“关闭”、“红眼消除”、“闪光灯”模式)
  • [get/set]WhiteBalance 使用一个WHITE_BALANCE_*常量设置白平衡校正来校正场景。在设置白平衡之前,可以使用getSupportedWhiteBalance方法来确认哪些设置可用
  • [get/set]AutoWhiteBalanceLock Android 4.0引入,使用自动白平衡算法,会暂停颜色校正算法。使用isAutoWhiteBalancLockSupported方法确认设备是否支持这种功能
  • [get/set]ColorEffect 使用EEFECT_*常量舍hi特殊颜色效果,使用getColorEffect可以找到可用的颜色效果
  • [get/set]FocusMode 使用FOCUS_MODE_*常量设置摄像头尝试对焦的方式(连续自动对焦在Android 4.0中引入)使用getSupportedFocusModes方法可以找出可用的模式。
  • [get/set]Antibanding 使用ANTIBANDING_*常量设置降低条带效果的屏幕刷新频率。

  • JPEG和缩略图质量 使用setJpegQuality和setJpegThumbnailQuality方法,并传入0到100之间的证书设置图像质量
  • 图像、预览和缩略图大小 分别使用setPictureSize、setPreviewSize和setJpegThumbnailSize方法制定图像、预览和缩略图的高度和宽度。使用getSupportedPictureSize、getSupportedPreviewSizes和getSupportededJpegThumbnailSize方法来确定有效值,返回Camera.Size对象的列表。
  • 图像和预览像素格式 使用PixelFormat类的静态常量调用setPictyreFormatsetPreviewFormat设置图像的格式。在使用getSupportedPictureFormats和getSupportedPreviewFormats方法返回支持的格式的一个列表。
  • 预览帧速率 setPreviewFpsRange方法取代了弃用的setPreviewFpsRangeFrameRate(Android 2.3)指定预览的首选帧率范围。使用getSupportedPreviewFpsRange方法可以找出支持的最低和最高帧率。
  1. 控制自动对焦、对焦区域和测光区域
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Camera.Parameters parameters = camera.getParameters();
    if(parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
    camera.autoFocus(new Auto FocusCallback(){
    public void onAutoFocus(boolean success,Camera camera){
    //
    }
    });
    }

Android 4.0引入两个对焦的API,用于在对焦图像或者确定场景的白平衡和亮度时指定对焦区域和侧光区域。
使用getMaxNumFocusAreas方法来确定设备是否支持该功能,返回值为检测到的最大对焦区域,如果为0,表示设备不支持定义对焦区域。
定义对焦区域使用setFocusAreas方法,传入一个Camera.Area对象的了表。
使用setMeteringAreas以同样的方式设置侧光区域。

  1. 使用摄像头预览
    不显示一个预览,食物无法使用Camera对象拍摄照片的。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    public class CameraActivity extends Activity implements SufaceHolder.Callback {
    private static final String TAG = "CameraActivity";

    private Camera camera;

    @Override
    public void onCreate(Bundle saveInstanceState) {
    super.onCreate(saveInstanceState);
    setContentView(R.layout.main);

    SufaceView surface = (SurfaceView)findViewById(R.id.surfaceView);
    SufaceHolder holder = surface.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SUREFACE_TYPE_PUSH_BUFFERS);
    holder.setFixed(400,300);
    }

    public void surfaceCreated(SurfaceHolder holder){
    try{
    camera.setPreviewDisplay(holder);
    camera.startPreview();
    } catch (IOException e) {
    //
    }
    }

    public void surfaceDestroyed(SurfaceHolder holder){
    camera.stopPreview();
    }

    public void surfaceChanged(SurfaceHolder holder,int format,int width,int height) {

    }

    @Override
    protected void onPaues(){
    super.onPause();
    camera.release();
    }

    @Override
    protected void onResume(){
    super.onResume();
    camera = Camera.open();
    }
    }

调用camera的setPreviewCallback方法传入PreviewCallback,监听每个预览帧

1
2
3
4
5
6
7
8
9
10
camera.setPreviewCallback(new PreviewCallback(){
public void onPreviewFrame(byte[] data,Camera camera) {
int quality = 60;

Size[] previewSize = camera.getParameters().getPreviewSize();
YuvImage iamge = new YuvImage(data,ImageFormat.NV21,previewSize.width,previewSize.height,null);
ByteArrayOutStream outputStream = new ByteArrayOutStream();
image.compressToJpeg(new Rect(0,0,previewSize.width,previewSize.height),quality,outputStream);
}
});

  • LoaderManager
    一个与Activity和Fragment有关联的抽象类,用于管理一个或多个Loader实例。每个Activity或Fragment只能有一个LoaderManager。
  • LoaderManager.LoaderCallbacks
    提供了客户端的一个callback接口,用于和LoaderManager进行交互。
  • AsyncTaskLoader
    一个抽象Loader,提供了一个AsyncTask进行工作
  • CursorLoader
    AsyncTaskLoader的子类,用于向ContentResover请求,返回一个Cursor。

使用LoaderManagerCallbacks

LoaderManager.LoaderCallbacks是callback接口,包含三个方法:

  • onCreateLoader() — 实例化和返回一个新创建的给定ID的loader
  • onLoadFinished() — 当一个创建好的loader完成了load,调用此函数
  • onLoaderReset() — 当一个创建好的loader要被reset时,调用此函数

  1. 添加jar包及资源文件
    下载SDK,将jar包添加到libs目录下,res文件合并到自己的目录下。
  2. 配置AndroidManifest.xml
    打开AndroidManifest.xml, 在标签中添加Activity, APPKEY, 和权限

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <manifest……>
    <application ……>
    <activity android:name="com.umeng.fb.ConversationActivity"
    android:theme="@android:style/Theme.NoTitleBar"/>
    <activity android:name="com.umeng.fb.ContactActivity"
    android:theme="@android:style/Theme.NoTitleBar"/>
    <meta-data android:value="YOUR_APP_KEY" android:name="UMENG_APPKEY"></meta-data>
    <meta-data android:value="Channel ID" android:name="UMENG_CHANNEL"/>
    </application>
    <uses-sdk android:minSdkVersion="4"></uses-sdk>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    </manifest>
  3. 调用代码

    1
    2
    FeedbackAgent agent = new FeedbackAgent(context);
    agent.startFeedbackActivity();

利用Gson和Volley实现URL读取JSON数据转model类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
GsonRequest<T> extends Request<T> {
private final GSON gson = new Gson();
private final Class<T> clazz;
private final Map<String,String> headers;
private final Listener<T> listener;

public GsonRequest(String url,Class<T> clazz,Map<String,String> headers,Listener<T> listener,ErrorListener errorListener){
super(Method.GET,url,errorListener);
this.clazz = clazz;
this.headers headers;
this.listener = listener;
}

@Override
public Map<String,String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}

@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}

@Override
protected Response<T> parseNetworkResponse(NetWorkResponse response) {
try {
String json = new String(response.data,HttpHeaderParser.parseCharset(response.headers));
return Response.success(gson.fromJson(json,clazz),HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}

  • 使用
  1. 创建executeRequest方法

    1
    2
    3
    void executeRequest(Request request) {
    RequestManager.addRequest(request, this);
    }
  2. 调用请求

    1
    executeRequest(new GsonRequest<Model>(url,Model.class,null,listener,errorListner);
  3. 在listener中处理数据

    1
    2
    3
    4
    5
    6
    new Listner<Moderl>(){
    @Override
    public void onResponse(final Model requestData) {
    //
    }
    }

1.导入SDK所需jar包

下载SDK的自拍包,将libs中的文件添加到libs

2.添加资源

将SDK包中的res文件夹中的资源添加到res目录中,友盟的资源文件全以umeng_开头

3.配置AndroidManifest.xml

<manifest>标签下添加权限

1
2
3
4
5
6
7
8
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
```
在`<application>`标签下添加`APPKEY`,其中Channel为推广渠道
```xml
<meta-data android:value="YOUR APP KEY" android:name="UMENG_APPKEY"/>
<meta-data android:value="Channel ID" android:name="UMENG_CHANNEL"/>

<application>标签下添加Service和Activity

1
2
3
4
5
6
7
8
<service
android:name="com.umeng.update.net.DownloadingService"
android:process=":DownloadingService" >
</service>
<activity
android:name="com.umeng.update.UpdateDialogActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
</activity>

4.调用更新接口

1
2
3
4
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
UmengUpdateAgent.update(this);
}

默认只在wifi条件下弹出更新,调用UmengUpdateAgent.setUpdateOnlyWifi(false)关闭。

5. 上传最新的APK

上传位置:登录友盟开发者后台,在左上角选择应用后,右边可以看到统计分析、组件、管理三部分。点击组件,左侧就会出现自动更新条目。请点击进入,即可找到上传的入口。友盟根据客户端的版本号来判断新旧(VersionCode)。

6. 集成检测

v2.4版本以后的SDK中默认开启了集成检测功能,在调用任意的更新接口后,我们将替您自动检查上述集成过程中2、3两个步骤是否被正确完成。 如果正确完成不会出现任何提示,否则会以如下的toast提示您。
你可以通过调用UmengUpdateAgent.setUpdateCheckConfig(false)来禁用此功能。

toast的含义如下:
“Please copy all resources (res/) from SDK to your project!”:请检查是不是把res文件夹下所有的资源文件都放到了工程中。
“Please add Permission in AndroidManifest!”:请检查上述步骤3.1中的相关权限是否正确添加。
“Please add Activity in AndroidManifest!”:请检查上述步骤3.3中的Activity是否正确添加。
“Please add Service in AndroidManifest!”:请检查上述步骤3.3中的Service是否正确添加。
“Please set umeng appkey!”:请检查上述步骤3.2中的APPKEY是否正确添加。

音乐

以『虾米音乐』为例,歌曲页面有个『转帖』选项,将html代码或javascript代码复制到文中即可。

1
<embed src="http://www.xiami.com/widget/0_1773340641/singlePlayer.swf" type="application/x-shockwave-flash" width="257" height="33" wmode="transparent"></embed>

视频

嵌入视频的方法和音乐类似,视频网站每个视频页面都会有一个『分享』或『转帖』按钮,点击可以查看代码。

1
<embed src="http://player.youku.com/player.php/sid/XNzQxMjU2ODI0/v.swf" allowFullScreen="true" quality="high" width="480" height="400" align="middle" allowScriptAccess="always" type="application/x-shockwave-flash"></embed>

showAsAction

  • always:一直显示在Action Bar上
  • isRoom:如果有足够空间,这个值就会显示在Action Bar上
  • nerver:永远不会出现在Action Bar上
  • withText:起显示文本标题
  • collapse:声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。否则,
    这个操作视窗在默认的情况下是可见的,并且即便在用于不适用的时候,也要占据操作栏的有效空间。
    一般要配合ifRoom一起使用才会有效果。

    隐藏域显示

    1
    2
    actionBar.hide();
    actionBar.show();

Action 下拉导航、视窗导航、标签导航

  • 下拉导航

  1. 初始化一个SpinnerAdapter

    1
    SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this,R.array.action_list,android.R.layout.simple_spinner_dropdown_item);
  2. 生成一个OnNavigationListener来响应ActionBar的菜单项点击操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    OnNavigationListener mOnNavigationListener = new OnNavigationListener() {  
    @Override
    public boolean onNavigationItemSelected(int position, long itemId) {
    Fragment newFragment = null;
    switch (position) {
    case 0:
    newFragment = new Fragment1();
    break;
    case 1:
    newFragment = new Fragment2();
    break;
    case 2:
    newFragment = new Fragment3();
    break;
    default:
    break;
    }
    getSupportFragmentManager().beginTransaction()
    .replace(R.id.container, newFragment, strings[position])
    .commit();
    return true;
    }
    };
  3. 绑定适配器和监听器到ActionBar

    1
    2
    3
    4
    actionBar = getActionBar();  
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);//导航模式必须设为NAVIGATION_MODE_LIST
    actionBar.setListNavigationCallbacks(mSpinnerAdapter,
    mOnNavigationListener);
  • 视窗模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="utf-8"?>  
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

<item
android:id="@+id/menu_search"
android:actionViewClass="android.widget.SearchView"
android:icon="@drawable/ic_menu_search"
android:showAsAction="ifroom"
android:title="搜索"/>
<item
android:id="@+id/menu_share"
android:actionProviderClass="android.widget.ShareActionProvider"
android:showAsAction="never"
android:title="分享"/>
<item
android:id="@+id/menu_setting"
android:actionProviderClass="com.example.tabdemo.MyActionProvider"
android:showAsAction="never"
android:title="设置">
<menu>
<item
android:id="@+id/menu_theme"
android:actionProviderClass="com.example.tabdemo.MyActionProvider"
android:showAsAction="always|withText"
android:title="更换主题"/>
<item
android:id="@+id/menu_system"
android:actionProviderClass="com.example.tabdemo.MyActionProvider"
android:showAsAction="always|withText"
android:title="系统设置"/>
</menu>
</item>
</menu>
  • actionProviderClass:指定一个构建视图所使用的布局资源,还可以使用actionLayout或者actionViewClass。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
getMenuInflater().inflate(R.menu.options, menu);  

//搜索视窗,因为showAsAction="ifRoom",所以图三中出现了搜索按钮
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search)
.getActionView();

//分享视窗,因为showAsAction="never",所以只能在溢出菜单中才看见到
ShareActionProvider mShareActionProvider = (ShareActionProvider) menu
.findItem(R.id.menu_share).getActionProvider();
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
mShareActionProvider.setShareIntent(shareIntent);

//设置视窗,MyActionProvider就是我们自定义的ActionProvider
MyActionProvider myactionprovider = (MyActionProvider) menu.findItem(
R.id.menu_setting).getActionProvider();
return super.onCreateOptionsMenu(menu);
  • 实现自定义MyActionProvider
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class MyActionProvider extends ActionProvider{  

    private Context context;
    private LayoutInflater inflater;
    private View view;
    private ImageView button;
    public MyActionProvider(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    this.context = context;
    inflater = LayoutInflater.from(context);
    view = inflater.inflate(R.layout.myactionprovider, null);
    }


    @Override
    public View onCreateActionView() {
    // TODO Auto-generated method stub
    button = (ImageView) view.findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
    Toast.makeText(context, "是我,没错", Toast.LENGTH_SHORT).show();
    }
    });
    return view;
    }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
listView.setOnScrollListener(new OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView view,int scrollState){

}

@Override
public void onScoll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totallItemCout){
if(firstVisibleItem == 0){
// 滑到顶部
}
if(visibleItemCount+firstVisibleItem == totalItemCount) {
// 滑到底部
}
}
})