看了一个开源的一个小项目,是制作联系人电话、短信还有应用的桌面快捷方式的,先将效果图贴上:
public class CreateShortCutActivity extends ListActivity implements DialogInterface.OnClickListener,
DialogInterface.OnCancelListener{
private static final int REQUEST_PHONE = 1;
private static final int REQUEST_TEXT = 2;
private static final int REQUEST_ACTIVITY = 3;
private static final int REQUEST_CUSTOM = 4;
private static final int LIST_ITEM_DIRECT_CALL = 0;
private static final int LIST_ITEM_DIRECT_TEXT = 1;
private static final int LIST_ITEM_ACTIVITY = 2;
private static final int LIST_ITEM_CUSTOM = 3;
private static final int DIALOG_SHORTCUT_EDITOR = 1;
private Intent mEditorIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setListAdapter(ArrayAdapter.createFromResource(this, R.array.mainMenu, android.R.layout.simple_list_item_1));
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
switch (position) {
case LIST_ITEM_DIRECT_CALL:{
Intent intent = new Intent(Intent.ACTION_PICK, Phones.CONTENT_URI);
intent.putExtra(Contacts.Intents.UI.TITLE_EXTRA_KEY, R.string.callShortcutActivityTitle);
startActivityForResult(intent, REQUEST_PHONE);
break;
}
case LIST_ITEM_DIRECT_TEXT:{
Intent intent = new Intent(Intent.ACTION_PICK, Phones.CONTENT_URI);
intent.putExtra(Contacts.Intents.UI.TITLE_EXTRA_KEY,
getText(R.string.textShortcutActivityTitle));
startActivityForResult(intent, REQUEST_TEXT);
break;
}
case LIST_ITEM_ACTIVITY:
break;
case LIST_ITEM_CUSTOM:
break;
default:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
return;
}
switch (requestCode) {
case REQUEST_PHONE:
startShortcutEditor(generateShortcutIntent(data,
R.drawable.sym_action_call, "tel", Intent.ACTION_CALL));
break;
case REQUEST_TEXT: {
startShortcutEditor(generateShortcutIntent(data,
R.drawable.sym_action_sms, "smsto", Intent.ACTION_SENDTO));
break;
}
case REQUEST_ACTIVITY:
break;
case REQUEST_CUSTOM:
break;
default:
break;
}
}
private void startShortcutEditor(Intent shortcutIntent) {
mEditorIntent = shortcutIntent;
showDialog(DIALOG_SHORTCUT_EDITOR);
}
/**
* Returns an Intent describing a direct text message shortcut
* @param data The data from the phone number picker
* @param actionResId
* @param scheme
* @param action
* @return An Intent describing a phone number shortcut
*/
private Intent generateShortcutIntent(Intent data, int actionResId,
String scheme, String action) {
Uri phoneUri = data.getData();
long personId = 0;
String name = null;
String number = null;
int type;
Cursor cursor = getContentResolver().query(phoneUri,
new String[]{Phones.PERSON_ID, Phones.NAME, Phones.NUMBER, Phones.TYPE},
null, null, null);
try {
cursor.moveToFirst();
personId = cursor.getLong(0);
name = cursor.getString(1);
number = cursor.getString(2);
type = cursor.getInt(3);
}finally{
if (null != cursor) {
cursor.close();
}
}
Intent intent = new Intent();
Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, personId);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, generatePhoneNumberIcon(personUri, type, actionResId));
//Make the URI a direct call ,so that it will always continue to work.
phoneUri = Uri.fromParts(scheme, number, null);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(action, phoneUri));
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
return intent;
}
/**
* Generates a phone number shortcut icon.Adds an overlay describing the type of the phone number ,
* add if there is a photo also adds the call action icon
* @param personUri The person the phone number belongs to
* @param type The type of the phone number
* @param actionResId The ID fot the action resource
* @return The bitmap for the icon
*/
private Bitmap generatePhoneNumberIcon(Uri personUri, int type,
int actionResId) {
final Resources resources = getResources();
boolean drawPhoneOverlay = true;
Bitmap photo = People.loadContactPhoto(this, personUri, 0, null);
if (null == photo) {
//If there is not a photo use the generic phone action icon instead
Bitmap phoneIcon = getPhoneActionIcon(resources, actionResId);
if(null != phoneIcon){
photo = phoneIcon;
drawPhoneOverlay = false;
}else{
return null;
}
}
//Set up the drawing class
int iconSize = (int)resources.getDimension(android.R.dimen.app_icon_size);
Bitmap icon = Bitmap.createBitmap(iconSize, iconSize, Config.ARGB_8888);
Canvas canvas = new Canvas(icon);
//Copy in the photo
Paint photoPaint = new Paint();
photoPaint.setDither(true);
photoPaint.setFilterBitmap(true);
Rect src = new Rect(0, 0, photo.getWidth(), photo.getHeight());
Rect dst = new Rect(0, 0, iconSize, iconSize);
canvas.drawBitmap(photo, src, dst, photoPaint);
// Create an overlay for the phone number type
String overlay = null;
switch (type) {
case Phones.TYPE_HOME:
overlay = "H";
break;
case Phones.TYPE_MOBILE:
overlay = "M";
break;
case Phones.TYPE_WORK:
overlay = "W";
break;
case Phones.TYPE_PAGER:
overlay = "P";
break;
case Phones.TYPE_OTHER:
overlay = "O";
break;
}
if (overlay != null) {
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
textPaint.setTextSize(20.0f);
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
textPaint.setColor(resources.getColor(R.color.textColorIconOverlay));
textPaint.setShadowLayer(3f, 1, 1, resources.getColor(R.color.textColorIconOverlayShadow));
canvas.drawText(overlay, 2, 16, textPaint);
}
return icon;
}
/**
* Return the phone action icon
* @param resources The resource to load the icon from
* @param actionResId The resource id to load
* @return The icon for the phone action icon
*/
private Bitmap getPhoneActionIcon(Resources resources, int resId) {
Drawable phoneIcon = resources.getDrawable(resId);
if (phoneIcon instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable)phoneIcon;
return bitmapDrawable.getBitmap();
}else {
return null;
}
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_SHORTCUT_EDITOR:
return new ShortcutEditorDialog(this, this, this);
default:
break;
}
return super.onCreateDialog(id);
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
switch (id) {
case DIALOG_SHORTCUT_EDITOR:
if (null != mEditorIntent) {
ShortcutEditorDialog editorDialog = (ShortcutEditorDialog)dialog;
editorDialog.setIntent(mEditorIntent);
mEditorIntent = null;
}
break;
default:
break;
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON1) {
ShortcutEditorDialog editorDialog = (ShortcutEditorDialog)dialog;
Intent intent = editorDialog.getIntent();
installShortcut(intent);
}
removeDialog(DIALOG_SHORTCUT_EDITOR);
}
private void installShortcut(Intent intent) {
//Broadcast an intent that tells the home screen to create a new shortcut
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
sendBroadcast(intent);
// Inform the user that the shortcut has been created
Toast.makeText(this, R.string.shortcutCreated, Toast.LENGTH_SHORT).show();
}
public void onCancel(DialogInterface dialog) {
// Remove the dialog, it won't be used again
removeDialog(DIALOG_SHORTCUT_EDITOR);
}
}
public class ShortcutEditorDialog extends AlertDialog implements OnClickListener, TextWatcher{
private static final String STATE_INTENT = "intent";
private boolean mCreated = false;
private Intent mIntent;
private ImageView mIconView;
private EditText mNameView;
private OnClickListener mClickListener;
private OnCancelListener mCancelListener;
protected ShortcutEditorDialog(Context context, OnClickListener clickListener,
OnCancelListener cancelListener) {
super(context);
mClickListener = clickListener;
mCancelListener = cancelListener;
View view = getLayoutInflater().inflate(R.layout.shortcut_editor, null, false);
setTitle(R.string.shortcutEditorTitle);
setButton(context.getString(android.R.string.ok), this);
setButton2(context.getText(android.R.string.cancel), mClickListener);
setOnCancelListener(mCancelListener);
setCancelable(true);
setView(view);
mIconView = (ImageView)view.findViewById(R.id.shortcutIcon);
mNameView = (EditText)view.findViewById(R.id.shortcutName);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
if(null != savedInstanceState){
mIntent = savedInstanceState.getParcelable(STATE_INTENT);
}
mCreated = true;
if (null != mIntent) {
loadIntent(mIntent);
}
}
private void loadIntent(Intent intent) {
// Show the icon
Bitmap iconBitmap = intent.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
if (null != iconBitmap) {
mIconView.setImageBitmap(iconBitmap);
} else {
ShortcutIconResource shortIconResource = intent
.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
if (null != shortIconResource) {
int res = getContext().getResources().getIdentifier(
shortIconResource.resourceName, null,
shortIconResource.packageName);
mIconView.setImageResource(res);
} else {
mIconView.setVisibility(View.INVISIBLE);
}
}
// Fill in the name field for editing
mNameView.addTextChangedListener(this);
mNameView.setText(intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME));
// Ensure the intent has the proper flags
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == BUTTON1) {
String name = mNameView.getText().toString();
if (null == name || (null != name && name.length() ==0)) {
mNameView.setError(getContext().getText(R.string.errorEmptyName));
return;
}
mIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
}
mClickListener.onClick(dialog, which);
}
public void setIntent(Intent intent) {
mIntent = intent;
if (mCreated) {
loadIntent(mIntent);
}
}
public Intent getIntent() {
mIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, mNameView.getText().toString());
return mIntent;
}
@Override
public void afterTextChanged(Editable text) {
if (text.length() == 0) {
mNameView.setError(getContext().getText(R.string.errorEmptyName));
}else
mNameView.setError(null);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}
程序的序列图如下:
转载:http://www.moandroid.com/?p=1699
在应用程序中添加快捷图标
Launcher为了让其他应用程序能够定制自己的快捷图标,就注册了一个BroadcastReceiver专门接收其他应用程序发来的快捷图标定制信息。所以只需要根据该BroadcastReceiver构造出相对应的Intent并装入我们的定制信息,最后调用sendBroadcast方法就可以创建一个快捷图标了。那么,要构造怎样一个Intent才会被Launcher的BroadcastReceiver接收呢?我们还是先来看看这个BroadcastReceiver的注册信息吧。
下面是Launcher的AndroidManifest.xml文件中Install-ShortcutReceiver的注册信息。
<!– Intent received used to install shortcuts from other applications –>
<receiver
android:name=”.InstallShortcutReceiver”
android:permission= “com.android.launcher.permission.INSTALL_SHORTCUT”>
<intent-filter>
<action android:name=”com.android.launcher.action.INSTALL_SHORTCUT” />
</intent-filter>
</receiver>
如何向这个 BroadcastReceiver 发送广播,设置如下:
1.首先应用程序必须要有com.android.launcher.permission.INSTALL_SHORTCUT权限;
2..然后广播出去的Intent的action设置com.android.launcher.action.INSTALL_SHORTCUT;
3.这样广播就可以发送给Launcher的InstallShortcutReceiver了;
而快捷图标的信息则是以附加信息的形式存储在广播出去的Intent对象中的,包括有图标、显示的名称以及用来启动目标组件的Intent这三种信息。我们可以通过putExtra的重载方法,通过指定相应的键值,将这些信息放到附加信息的Bundle对象中。
列出了各种快捷图标信息相对应的键值和数据类型:
下面举些具体的例子,如下:
private final String ACTION_ADD_SHORTCUT =
“com.android.launcher.action.INSTALL_SHORTCUT”;
Intent addShortcut =new Intent(ACTION_ADD_SHORTCUT);
String numToDial = null;
Parcelable icon = null;
numToDial = “110″;
icon = Intent.ShortcutIconResource.fromContext(this,R.drawable.jing);
//numToDial = “119″;
//icon = Intent.ShortcutIconResource.fromContext(this,R.drawable.huo);
//图标
addShortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,icon);
//名称
addShortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME,numToDial);
//启动目标组件的Intent
Intent directCall;
directCall.setData(Uri.parse(“tel://”+numToDial));
addShortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT,directCall);
sendBroadcast(addShortcut);
上面的程序运行后的界面如下:
只要知道这些信息后,你就可以轻而易举的为应用程序添加快捷图标。