2011年8月31日 星期三

Youtube/Market Intent for Search in Android

Here is a trick that would help other applications that need to open search results for videos based on a particular keyword.

You need to create an implicit Intent and trigger it. Here is a snippet of code that works.

For Youtube
Intent intent = new Intent(Intent.ACTION_SEARCH);
intent.setPackage("com.google.android.youtube");
intent.putExtra("query", "Android");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Here, "Android" is the keyword. Now, the Youtube app will show you videos with the keyword "Android"

For Market 
Similarly, by changing only the package name, you can bring up search results with the Android Market app as well.

Intent intent = new Intent(Intent.ACTION_SEARCH);
intent.setPackage("com.android.vending");
intent.putExtra("query", "Android");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

For Contacts
The package name for the Contacts app is "com.google.contacts". 

You just need the package name of the target app if you don't want the Resolver activity to show up. This might work for other google apps as well. I haven't checked though.

2011年8月26日 星期五

獲取手機屏幕大小


1、獲取屏幕的分辨率(因為android中處理顯示的時候,需要根據屏幕分辨率的不同才去不同的佈局或顯示不同的素材)
Java代碼 
// 通過WindowManager獲取  
DisplayMetrics dm = new DisplayMetrics();  
getWindowManager().getDefaultDisplay().getMetrics(dm);  
System.out.println("heigth : " + dm.heightPixels);  
System.out.println("width : " + dm.widthPixels);  
// 通過Resources獲取          
DisplayMetrics dm2 = getResources().getDisplayMetrics();  
System.out.println("heigth2 : " + dm2.heightPixels);  
System.out.println("width2 : " + dm2.widthPixels);    
// 獲取屏幕的默認分辨率  
Display display = getWindowManager().getDefaultDisplay();  
System.out.println("width-display :" + display.getWidth());  
System.out.println("heigth-display :" + display.getHeight());
// 通過WindowManager獲取
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
System.out.println("heigth : " + dm.heightPixels);
System.out.println("width : " + dm.widthPixels);
// 通過Resources獲取 
DisplayMetrics dm2 = getResources().getDisplayMetrics();
System.out.println("heigth2 : " + dm2.heightPixels);
System.out.println("width2 : " + dm2.widthPixels);
// 獲取屏幕的默認分辨率
Display display = getWindowManager().getDefaultDisplay();
System.out.println("width-display :" + display.getWidth());
System.out.println("heigth-display :" + display.getHeight());
2、去掉屏幕標題及全屏顯示
Java代碼 
// 去掉標題  
requestWindowFeature(Window.FEATURE_NO_TITLE);  
// 設置全屏  
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
        WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 去掉標題
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 設置全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  WindowManager.LayoutParams.FLAG_FULLSCREEN);
3、設置屏幕的風向
在Manifest.xml文件中配置Activity的屬性
Xml代碼 
<activity android:name=".AnimateActivity" android:label="@string/app_name" 
    android:screenOrientation="landscape"><!--landscape 橫屏portrait 豎屏--> 
    <intent-filter> 
        <action android:name="android.intent.action.MAIN" /> 
        <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</activity>
<activity android:name=".AnimateActivity" android:label="@string/app_name"
 android:screenOrientation="landscape"><!--landscape 橫屏portrait 豎屏-->
 <intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
</activity>
在程序中控制,一般在Activity中的onCreate、onDestroy方法中控制,因為在屏幕方向發生變化時,
系統會重新啟動Activity。所以需要再Activity銷毀前保存相關數據,方便在下次onCreate方法中
重新加載,並更新屏幕的佈局
Java代碼 
public void onCreate(Bundle savedInstanceState) {  
    //強制橫屏  
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
    // TODO 更新屏幕佈局  
}  

public void onDestroy() {  
    if(getRequestedOrientation() ==  
            ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){  
        // 保存數據  
    }else if(getRequestedOrientation() ==  
            ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){  
        // 保存數據  
    }  

Android Bitmap Scaling

http://zerocredibility.wordpress.com/2011/01/27/android-bitmap-scaling/


Scaling images is a common task for many applications including those written for Android. The most obvious approach, as described on this page, won’t work in most cases. The problem as you would soon find out if you tried it is that your phone doesn’t have enough memory. Luckily we can get around that, but not easily.
The trick ends up being a two step process. First we decode the bitmap, setting the sampling level as high as we can while avoiding loss of quality, then we scale this smaller bitmap in memory down to the exact specified size. I’ve included this in a nicely packaged class BitmapScaler, included at the end of this post.The class itself looks quite long but this is only because it has the flexibility of scaling bitmaps from resources, assets, and files.
BitmapScaler preserves the aspect ratio. You may only pass a new width. The resulting height will be scaled equal to the amount the width was scaled.
For example,
1BitmapScaler scaler = newBitmapScaler(getResources(), R.drawable.moorwen, newWidth);
2imageView.setImageBitmap(scaler.getScaled());
BitmapScaler class follows,

class BitmapScaler {
	private static class Size {
		int sample;
		float scale;
	}

	private Bitmap scaled;

	BitmapScaler(Resources resources, int resId, int newWidth)
			throws IOException {
		Size size = getRoughSize(resources, resId, newWidth);
		roughScaleImage(resources, resId, size);
		scaleImage(newWidth);
	}

	BitmapScaler(File file, int newWidth) throws IOException {
		InputStream is = null;
		try {
			is = new FileInputStream(file);
			Size size = getRoughSize(is, newWidth);
			try {
				is = new FileInputStream(file);
				roughScaleImage(is, size);
				scaleImage(newWidth);
			} finally {
				is.close();
			}
		} finally {
			is.close();
		}
	}

	BitmapScaler(AssetManager manager, String assetName, int newWidth)
			throws IOException {
		InputStream is = null;
		try {
			is = manager.open(assetName);
			Size size = getRoughSize(is, newWidth);
			try {
				is = manager.open(assetName);
				roughScaleImage(is, size);
				scaleImage(newWidth);
			} finally {
				is.close();
			}
		} finally {
			is.close();
		}
	}

	Bitmap getScaled() {
		return scaled;
	}

	private void scaleImage(int newWidth) {
		int width = scaled.getWidth();
		int height = scaled.getHeight();

		float scaleWidth = ((float) newWidth) / width;
		float ratio = ((float) scaled.getWidth()) / newWidth;
		int newHeight = (int) (height / ratio);
		float scaleHeight = ((float) newHeight) / height;

		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);

		scaled = Bitmap.createBitmap(scaled, 0, 0, width, height, matrix, true);
	}

	private void roughScaleImage(InputStream is, Size size) {
		Matrix matrix = new Matrix();
		matrix.postScale(size.scale, size.scale);

		BitmapFactory.Options scaledOpts = new BitmapFactory.Options();
		scaledOpts.inSampleSize = size.sample;
		scaled = BitmapFactory.decodeStream(is, null, scaledOpts);
	}

	private void roughScaleImage(Resources resources, int resId, Size size) {
		Matrix matrix = new Matrix();
		matrix.postScale(size.scale, size.scale);

		BitmapFactory.Options scaledOpts = new BitmapFactory.Options();
		scaledOpts.inSampleSize = size.sample;
		scaled = BitmapFactory.decodeResource(resources, resId, scaledOpts);
	}

	private Size getRoughSize(InputStream is, int newWidth) {
		BitmapFactory.Options o = new BitmapFactory.Options();
		o.inJustDecodeBounds = true;
		BitmapFactory.decodeStream(is, null, o);

		Size size = getRoughSize(o.outWidth, o.outHeight, newWidth);
		return size;
	}

	private Size getRoughSize(Resources resources, int resId, int newWidth) {
		BitmapFactory.Options o = new BitmapFactory.Options();
		o.inJustDecodeBounds = true;
		BitmapFactory.decodeResource(resources, resId, o);

		Size size = getRoughSize(o.outWidth, o.outHeight, newWidth);
		return size;
	}

	private Size getRoughSize(int outWidth, int outHeight, int newWidth) {
		Size size = new Size();
		size.scale = outWidth / newWidth;
		size.sample = 1;

		int width = outWidth;
		int height = outHeight;

		int newHeight = (int) (outHeight / size.scale);

		while (true) {
			if (width / 2 < newWidth || height / 2 < newHeight) {
				break;
			}
			width /= 2;
			height /= 2;
			size.sample *= 2;
		}
		return size;
	}
}
Or, try out the Eclipse test project.

利用BitmapFactory.Options的inSampleSize對bitmap進行優化

在我的舊文章"從內部文件夾加載圖像視圖(ImageView)", "從SD Card加載圖像視圖(ImageView), 使用BitmapFactory"和"從網絡加載圖像視圖(ImageView)"中, 我展示了如何顯示位圖(bitmap), 但都是把位圖直接顯示在ImageView上. 這樣做有一個問題: 就是對系統資源很"大食", 特別是當源位圖是非常大時, 甚至可以使應用程序崩潰.

這篇文章以"從SD Card加載圖像視圖(ImageView)"為例, 首先檢查源位圖的大小, 通過BitmapFactory.Options設置inSampleSize, 這樣做可以減少對系統資源的要求.

利用BitmapFactory.Options的inSampleSize對bitmap進行優化

先把較大的圖片文件複製到SD Card中.

main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<ImageView
android:id="@+id/imageview"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
/>
</LinearLayout>


Java源代碼
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
52
53
54
55
56
57
58
59
60
61
package com.AndroidImage;
 
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.Toast;
 
public class AndroidImage extends Activity {
 
private String imageFile = "/sdcard/AndroidSharedPreferencesEditor.png";
/** Called when the activity is first created. */
 
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
   
ImageView myImageView = (ImageView)findViewById(R.id.imageview);
//Bitmap bitmap = BitmapFactory.decodeFile(imageFile);
//myImageView.setImageBitmap(bitmap);
 
Bitmap bitmap;
float imagew = 300;
float imageh = 300;
 
BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options();
bitmapFactoryOptions.inJustDecodeBounds = true;
bitmap = BitmapFactory.decodeFile(imageFile, bitmapFactoryOptions);
 
int yRatio = (int)Math.ceil(bitmapFactoryOptions.outHeight/imageh);
int xRatio = (int)Math.ceil(bitmapFactoryOptions.outWidth/imagew);
 
if (yRatio > 1 || xRatio > 1){
 if (yRatio > xRatio) {
  bitmapFactoryOptions.inSampleSize = yRatio;
  Toast.makeText(this,
    "yRatio = " + String.valueOf(yRatio),
    Toast.LENGTH_LONG).show();
 }
 else {
  bitmapFactoryOptions.inSampleSize = xRatio;
  Toast.makeText(this,
    "xRatio = " + String.valueOf(xRatio),
    Toast.LENGTH_LONG).show();
 }
}
else{
 Toast.makeText(this,
   "inSampleSize = 1",
   Toast.LENGTH_LONG).show();
}
 
bitmapFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(imageFile, bitmapFactoryOptions);
myImageView.setImageBitmap(bitmap);
}
 
}