您的位置:首页 > 其它

复杂的社会,梦想的开端

2009-05-10 19:42 260 查看
Android特色开发

第一部分 传感器

传感器是一种物理装置或生物器官,能够探测、感受外界的信号、物理条件(如:光、热、湿度)或化学组成(如:烟雾),并将探知的信息传递给其他设备或器官。

Android支持的传感器有如下几种:

Sensor.TYPE_ACCELEROMETER加速度传感器

Sensor.TYPE_GYROSCOPE陀螺仪传感器

Sensor.TYPE_LIGHT亮度传感器

Sensor.TYPE_MAGNETIC_FIELD地磁传感器

Sensor.ORIENTATION方向传感器

Sensor.TYPE_PRESSURE压力传感器

Sensor.TYPE_PROXIMITY近程传感器

Sensor.TYPE_TEMPERATURE温度传感器

Android中传感器 (此特效必须在真机中才能看到效果)

Android传感器的使用需要掌握SensorManager和SensorEventListener

SensorManager 就是传感器的一个综合管理类

SensorManager mSensorManager = (SensorManger)getSystemService(SENSOR_SERVICE);//通过getSystemService得到SensorManager对象

List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ORIENTATION);//此处通过getSensorList获得我们需要的传感器类型,并保存到一个传感器列表中

Boolean mRegisteredSensor = mSensorManager.registerListener(this,sensors,SensorManager.SENSOR_DELAY_FASTEST);//通过registerListener注册一个监听器其中

方法中参数 this---接收信号的Listener

sensors---接收传感器类型的列表即上一步的List<Sensor>

SensorManager.SENSOR_DELAY_FASTEST---接收频度

此方法调用之后返回一个boolean值,true为成功 ,false为失败

mSensorManager.unregisterListener(this);//在不使用时需要通过unregisterListener卸载传感器

SensorEventListener 传感器的核心部分 以下两个方法必须实现

onSensorChanged(SensorEvent event) 此方法在传感器值更改时调用。该方法只由受此应用程序监视的传感器调用。

其中参数为SensorEvent对象,该对象包括一组浮点数,表示传感器获得的方向、加速度等信息如下:

float x = event.values[SensorManager.DATA_X];

float y = event.values[SensorManager.DATA_Y];

float z = event.values[SensorManager.DATA_Z];

onAccuracyChanged(Sensor sensor,int accuracy) 此方法在传感器的精准度发生改变时调用。

其中参数 第一个表示传感器 第二个表示传感器新的准确值

除上两种重要方法外还有以下几种

getDefaultSensor得到默认的传感器对象

getInclination得到地磁传感器倾斜角的弧度制

getOrientation得到设备选择的方向

getSensorList得到指定传感器列表

下例为实现了一个方向传感器的例子 实现了如何获得传感器的方向,加速度等信息,可以根据得到的数值与上一次得到的数值之间的关系进行需要操作。

public class Activity01 extends Activity implements SensorEventListener{

private booleanmRegisteredSensor;

private SensorManagermSensorManager;//定义SensorManager
public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mRegisteredSensor = false;

mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);//取得SensorManager实例

}

protected void onResume(){

super.onResume();

List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ORIENTATION);//接受SensorManager的一个列表(Listener),这里我们指定类型为TYPE_ORIENTATION(方向感应器)

if (sensors.size() > 0){

Sensor sensor = sensors.get(0);

mRegisteredSensor = mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST);//注册SensorManager,this->接收sensor的实例,第二个参数为接收传感器类型的列表,第三个参数为接受的频率

}

}

protected void onPause(){

if (mRegisteredSensor){

mSensorManager.unregisterListener(this);//通过unregisterListener来卸载\取消注册

mRegisteredSensor = false;

}

super.onPause();

}

public void onAccuracyChanged(Sensor sensor, int accuracy){//当进准度发生改变时调用此方法,sensor->传感器,accuracy->精准度

}

public void onSensorChanged(SensorEvent event){// 此方法在传感器在被改变时触发

if (event.sensor.getType() == Sensor.TYPE_ORIENTATION){// 接受方向感应器的类型

//这里我们可以得到数据,然后根据需要来处理,由于模拟器上面无法测试效果,因此我们暂时不处理数据

float x = event.values[SensorManager.DATA_X];

float y = event.values[SensorManager.DATA_Y];

float z = event.values[SensorManager.DATA_Z];

}

}

}

第二部分 语音识别

Android中通过RecognizerIntent来实现语音识别。

RecognizerIntent包含以下常量:

ACTION_RECOGNIZE_SPEECH开启语音活动

ACTION_WEB_SEARCH开启网络语音模式,结果将以网页搜索显示

EXTRA_LANGUAGE设置一个语言库

EXTRA_LANGUAGE_MODEL语音识别模式

EXTRA_MAX_RESULTS返回最大的结果

EXTRA_PROMPT提示用户可以开始语音了

EXTRA_RESULTS将字符串返回到一个ArrayList中

LANGUAGE_MODEL_FREE_FORM在一种语言模式上自由语音

LANGUAGE_MODEL_WEB_SEARCH使用语音模式在Web上搜索

RESULT_AUDIO_ERROR返回结果时,音频遇到错误

RESULT_CLIENT_ERROR返回结果时,客户端遇到错误

RESULT_NETWORK_ERROR返回结果时,网络遇到错误

RESULT_NO_MATCH没有检测到语音的错误

RESULT_SERVER_ERROR返回结果时,服务器遇到错误

在使用语音识别时需要通过Intent来传递一个动作以及一些属性,然后通过startActivityForResult来开始语音 代码如下:

Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RcognizerIntent.LANGUAGE_MODEL_FREE_FORM);

intent.putExtra(RecognizerIntent.EXTRA_PROMPT,"开始语音");

startActivityForResult(intent ,VOICE_RECOGNITION_REQUEST_CODE);//通过startActivityForResult来开始语音

另外还需要实现onActivityResult方法,当语音接收时,会触发来获得语音的字符序列。

下例中我们实现了 点击按钮时开始语音,并在onActivityResult方法中取得结果并显示出来

main.xml

<?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"

/>

<Button

android:id="@+id/Button01"

android:text="开始使用语音识别"

android:layout_width="fill_parent"

android:layout_height="wrap_content"/>

<ListView

android:id="@+id/ListView01"

android:layout_width="fill_parent"

android:layout_height="0dip"

android:layout_weight="1" />

</LinearLayout>

public class Activity01 extends Activity{

private static final int VOICE_RECOGNITION_REQUEST_CODE = 4321;

private ListView mList;

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mList = (ListView) findViewById(R.id.ListView01);

Button button = (Button) findViewById(R.id.Button01);

button.setOnClickListener(new View.OnClickListener() {

public void onClick(View v){

try{

Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);//通过Intent传递语音识别的模式,开启语音

intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);//语言模式和自由形式的语音识别

intent.putExtra(RecognizerIntent.EXTRA_PROMPT,"开始语音");//提示语音开始

startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);//开始执行我们的Intent、语音识别

}catch (ActivityNotFoundException e){//如果找不到设置,就会抛出ActivityNotFoundException

Toast.makeText(Activity01.this,"ActivityNotFoundException", Toast.LENGTH_LONG).show(); //找不到语音设备装置

}

}

});

}

protected void onActivityResult(int requestCode, int resultCode, Intent data){//当语音结束时的回调函数onActivityResult

if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK){// 判断是否是我们执行的语音识别

ArrayList<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);// 取得语音的字符

//设置视图更新

//mList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,results));

String resultsString = "";

for (int i = 0; i < results.size(); i++){

resultsString += results.get(i);

}

Toast.makeText(this, resultsString, Toast.LENGTH_LONG).show();

super.onActivityResult(requestCode, resultCode, data);

}

}

}

第三部分 账户管理

Android中通过android.accounts包中所包含的集中式的账户管理API,用于安全地存储和访问认证的令牌和密码。

android.accounts包中的功能:

AccountManagerCallback账户管理回调接口

AccountManagerFuture代表一个AccountMananger的异步调用结果

OnAccountUpdateListener账户监听回调接口

AbstractAccountAuthenticator创建AccountAuthenticators(账户验证)的一个基类

AccountAccountManager中的一个账户信息及类型

AccountAuthenticatorActivity用于实现一个AbstractAccountAuthenticator的活动

AccountAuthenticatorResponse账户验证响应

AccountManager账户管理器

AuthenticatorDescription一个Parcelable类型的值包括了账户验证的信息

mAccountManager = AccountManager.get(this);//通过AccountManager类的get方法获得AccountManager对象

AccountManager中的常用方法

addAccount添加一个账户

addOnAccountUpdatedListenenr添加一个账户更新的监听器

removeOnAccountsUpdatedListener取消一个账户更新的监听器

clearPassword清除指定账户的密码数据

getAccounts得到所有的账户信息

getAccountsByType得到指定类型的账户信息

getPassword得到指定账户的密码

setUserData设置指定账户的信息

setPassword设置指定账户的密码

removeAccount删除一个账户

public class SleepyAccountAuthenticatorActivity extends AccountAuthenticatorActivity{//此类供用户输入信息

protected void onCreate(Bundle icicle){

super.onCreate(icicle);

setContentView(R.layout.new_account);

final Button done = (Button) findViewById(R.id.new_account_done);

final EditText server = (EditText) findViewById(R.id.new_account_server);

final EditText username = (EditText) findViewById(R.id.new_account_username);

final EditText password = (EditText) findViewById(R.id.new_account_password);

final Activity self = this;

done.setOnClickListener(new OnClickListener() {

public void onClick(View v){

Account account = new Account(username.getText().toString(), getString(R.string.ACCOUNT_TYPE));//通过指定账户名和账户类型构建一个Account对象

Bundle userdata = new Bundle(); //将服务器数据通过Bundle方式加入进来

userdata.putString("SERVER", server.getText().toString());

AccountManager am = AccountManager.get(self);//取得AccountManager

if (am.addAccountExplicitly(account, password.getText().toString(), userdata)){//通添addAccountExplicitly向账户管理器中添加一个账户信息

Bundle result = new Bundle();

result.putString(AccountManager.KEY_ACCOUNT_NAME, username.getText().toString());

result.putString(AccountManager.KEY_ACCOUNT_TYPE, getString(R.string.ACCOUNT_TYPE));

setAccountAuthenticatorResult(result);

}

finish();

}

});

}

}

public class SleepyAccountAuthenticator extends AbstractAccountAuthenticator{//在添加、操作账户信息时会通过AbstractAccountAuthenticator实现异步调用

private String_tag = "SleepyAccountAuthenticator";

private Context_context;

public SleepyAccountAuthenticator(Context context){

super(context);

_context = context;

}

public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options)

throws NetworkErrorException{//添加账户addAccount方法

Log.d(_tag, accountType + " - " + authTokenType);

Bundle ret = new Bundle();

Intent intent = new Intent(_context, SleepyAccountAuthenticatorActivity.class);

intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);

ret.putParcelable(AccountManager.KEY_INTENT, intent);

return ret;

}

public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options){

Log.d(_tag, ".confirmCredentials");

return null;

}

public Bundle editProperties(AccountAuthenticatorResponse response, String accountType){

Log.d(_tag, ".editProperties");

return null;

}

public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle loginOptions) throws NetworkErrorException{

Log.d(_tag, ".getAuthToken");

return null;

}

public String getAuthTokenLabel(String authTokenType){

Log.d(_tag, ".getAuthTokenLabel");

return null;

}

public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException{

Log.d(_tag, ".hasFeatures");

return null;

}

public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle loginOptions){

Log.d(_tag, ".updateCredentials");

return null;

}

}

public class SleepyAccountsService extends Service{//账户服务类

private SleepyAccountAuthenticator_saa;

public IBinder onBind(Intent intent){

IBinder ret = null;

if (intent.getAction().equals(android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT)){

ret = getSleepyAuthenticator().getIBinder();//通过getIBinder方法返回一个IBinder

return ret;

}

}

private SleepyAccountAuthenticator getSleepyAuthenticator(){

if (_saa == null)

_saa = new SleepyAccountAuthenticator(this);

return _saa;

}

}

public class Activity01 extends Activity{

private String_tag= "Activity01";

private TextView_accountList;

private AccountManager_am;

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.manage_accounts);

_accountList = (TextView) findViewById(R.id.manage_accounts_accountlist);

_am = AccountManager.get(this);//取得AccountManager对象

Button newacc = (Button) findViewById(R.id.manage_accounts_newaccount);

final Activity self = this;

newacc.setOnClickListener(new OnClickListener() {

public void onClick(View v){

_am.addAccount(getString(R.string.ACCOUNT_TYPE), null, null, null, self, new AccountManagerCallback<Bundle>() {

@Override

public void run(AccountManagerFuture<Bundle> amfuture){

try{

Log.d(_tag, amfuture.getResult().toString());

}catch (Exception e){

Log.e(_tag, e.getMessage(), e);

}

listAccounts();

}

}, null);

}

});

listAccounts();

}

private void listAccounts(){//显示出所有账户

Account[] accounts = _am.getAccountsByType(getString(R.string.ACCOUNT_TYPE));//得到指定类型的账户

_accountList.setText("账户列表:");

for (Account account : accounts){

_accountList.setText(_accountList.getText().toString() + '\n' + account.name + " - " + account.type);

}

}

}

res.xml.authenticator.xml文件

<?xml version="1.0" encoding="utf-8"?>

<account-authenticator

xmlns:android="http://schemas.android.com/apk/res/android"

android:accountType="com.yarin.AccountType"

android:icon="@drawable/icon"

android:smallIcon="@drawable/icon"

android:label="@string/ACCOUNT_LABEL"

android:accountPreferences="@xml/account_preferences"

/>

res.xml.account_preferences.xml文件

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen

xmlns:android="http://schemas.android.com/apk/res/android">

</PreferenceScreen>

res.layout.new_account.xml文件

<?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="wrap_content"

android:layout_height="wrap_content"

android:text="用户名"

></TextView>

<EditText

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/new_account_username"

android:text="请输入用户名"

></EditText>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="密码"

></TextView>

<EditText

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/new_account_password"

android:text="请输入密码"

></EditText>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="服务器"

></TextView>

<EditText

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/new_account_server"

android:text="请输入账户服务器"

></EditText>

<Button

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/new_account_done"

android:text="完成"

></Button>

</LinearLayout>

res.layout.manage_account.xml文件

<?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"

>

<Button

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="新建账户"

android:id="@+id/manage_accounts_newaccount"

></Button>

<ScrollView

android:id="@+id/ScrollView01"

android:layout_height="fill_parent"

android:layout_width="fill_parent"

>

<TextView

android:text="@+id/TextView01"

android:layout_height="fill_parent"

android:layout_width="fill_parent"

android:id="@+id/manage_accounts_accountlist"

></TextView>

</ScrollView>

</LinearLayout>

AndroidManifest.xml文件

<?xml version="1.0" encoding="utf-8"?>

<manifest

xmlns:android="http://schemas.android.com/apk/res/android"

package="com.yarin.android.Examples_09_08"

android:versionCode="1"

android:versionName="1.0"

>

<application

android:icon="@drawable/icon"

android:label="@string/app_name"

>

<service //开启一个账户管理服务

android:name="SleepyAccountsService">

<intent-filter>

<action android:name="android.accounts.AccountAuthenticator" ></action>

</intent-filter>

<meta-data

android:name="android.accounts.AccountAuthenticator"

android:resource="@xml/authenticator">

</meta-data>

</service>

<activity

android:name=".auth.SleepyAccountAuthenticatorActivity"

>

<intent-filter>

<action

android:name="android.accounts.AccountAuthenticator"

></action>

</intent-filter>

</activity>

<activity

android:name="Activity01"

>

<intent-filter>

<action

android:name="android.intent.action.MAIN"

></action>

<category

android:name="android.intent.category.LAUNCHER"

></category>

</intent-filter>

</activity>

</application>

//因要对账户信息进行操作,需要在AndroidManifest.xml文件中对操作权限进行声明 确定API为5

<uses-sdk android:minSdkVersion="5"/>

<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"></uses-permission>

<uses-permission android:name="android.permission.ACCOUNT_MANAGER"></uses-permission>

<uses-permission android:name="android.permission.GET_ACCOUNTS"></uses-permission>

<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"></uses-permission>

</manifest>

第四部分 桌面组件

一、快捷方式

在应用程序中通过代码来将一个应用程序添加到Android的Shortcuts列表中。

下例实现了添加一个发送邮件的应用到快捷方式列表中去。

public class Activity01 extends Activity{

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

Intent addShortcut; //要添加的快捷方式的Intent

if (getIntent().getAction().equals(Intent.ACTION_CREATE_SHORTCUT)){//判断是否要添加快捷方式

addShortcut = new Intent();

addShortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, "发送邮件");//设置快捷方式的名字

Parcelable icon = Intent.ShortcutIconResource.fromContext(this,R.drawable.mail_edit); //构建快捷方式中专门的图标

addShortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,icon);//添加快捷方式图标 其实android提供了Intent.ShortcutIconResource.fromContext来创建快捷方式的图标,

最后通过setResult来返回构建一个快捷方式

Intent mailto = new Intent(Intent.ACTION_SENDTO, Uri.parse( "mailto:xxx@xxx.com" )); //构建快捷方式执行的Intent

addShortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, mailto); //添加快捷方式Intent 对应快捷方式执行的事件

setResult(RESULT_OK,addShortcut); //通过setResult来返回构建一个快捷方式

}else{

setResult(RESULT_CANCELED); //取消

}

finish(); //关闭

}

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest

xmlns:android="http://schemas.android.com/apk/res/android"

package="com.yarin.android.Examples_09_05"

android:versionCode="1"

android:versionName="1.0">

<application

android:icon="@drawable/icon" android:label="@string/app_name">

<activity

android:name=".Activity01"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

<action android:name="android.intent.action.CREATE_SHORTCUT" /> //注册时添加一个Action为android.intent.action.CREATE_SHORTCUT的IntentFilter

添加之后Shortcuts列表中就会出现应用程序的图标和名字

</intent-filter>

</activity>

</application>

<uses-sdk android:minSdkVersion="5" />

</manifest>

最后可以在Shortcuts列表中找到所添加的快捷方式,并可将其添加到桌面。

二、实时文件夹

Live Folders就是一个查看你的手机中所有电子书、电子邮件、ress订阅、播放列表的快捷方式,并且这些内容是实时更新的。

Live Folders本身不存储任何信息,都是以映射的方式查看其ContentProvider所指向的数据信息,并可以自定义显示格式,所以LiveFold可以实时的更新显示内容。

在开发时要确保所指定数据信息URI的ContentProvider支持文件夹查询。

Live Folders的常用属性

EXTRA_LIVE_FOLDER_BASE_INTENT选中选项后执行的事件

EXTRA_LIVE_FOLDER_NAME实时文件夹的名字

EXTRA_LIVE_FOLDER_ICON实时文件夹的图标

EXTRA_LIVE_FOLDER_DISPLAY_MODE实时文件夹的显示模式(列表和宫格)

下例中通过Live Folders调用电话本中的信息,当点击其中一条信息时,便执行呼叫该联系人的动作。

public class Activity01 extends Activity{

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

// setContentView(R.layout.main);

if (getIntent().getAction().equals(LiveFolders.ACTION_CREATE_LIVE_FOLDER)){// 判断是否创建实时文件夹

Intent intent = new Intent();//将实时文件夹的信息装入Intent对象

intent.setData(Uri.parse("content://contacts/live_folders/people"));// 设置数据地址

intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT, new Intent(Intent.ACTION_CALL, ContactsContract.Contacts.CONTENT_URI));// 设置当我们单击之后的事件,这里单击一个联系人后,呼叫

intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, "电话本");// 设置实时文件夹的名字

intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON, Intent.ShortcutIconResource.fromContext(this, R.drawable.contacts));// 设置实施文件夹的图标

intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE, LiveFolders.DISPLAY_MODE_LIST);// 设置显示模式为列表

setResult(RESULT_OK, intent);// 设置为Intent

}else{

setResult(RESULT_CANCELED);

}

finish();//结束Activity

}

}

AndroidManifest.xml文件

<?xml version="1.0" encoding="utf-8"?>

<manifest

xmlns:android="http://schemas.android.com/apk/res/android"

package="com.yarin.android.Examples_09_06"

android:versionCode="1"

android:versionName="1.0">

<application

android:icon="@drawable/icon" android:label="@string/app_name">

<activity

android:name=".Activity01"

android:label="@string/app_name">

<intent-filter> //注册一个action动作为android.intent.action.CREATE_LIVE_FOLDER的Intentfilter

<action android:name= "android.intent.action.CREATE_LIVE_FOLDER" />

<category android:name= "android.intent.category.DEFAULT" />

</intent-filter>

</activity>

</application>

<uses-sdk android:minSdkVersion="5" />

</manifest>

三、Widget开发

作用:可以显示即将到来的日历事件,或者一首后台播放的歌曲的详细信息。

public class ExampleAppWidgetProvider extends AppWidgetProvider{//创建一个Widget

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){//周期更新时调用

final int N = appWidgetIds.length;

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

int appWidgetId = appWidgetIds[i];

String titlePrefix = Activity01.loadTitlePref(context, appWidgetId);

updateAppWidget(context, appWidgetManager, appWidgetId, titlePrefix);

}

}

public void onDeleted(Context context, int[] appWidgetIds){//当桌面部件删除时调用

//删除appWidget

final int N = appWidgetIds.length;

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

Activity01.deleteTitlePref(context, appWidgetIds[i]);

}

}

public void onEnabled(Context context){//当AppWidgetProvider提供的第一个部件被创建时调用

PackageManager pm = context.getPackageManager();

//用ComponentName来表示应用程序中某个组件的完整名字

pm.setComponentEnabledSetting(new ComponentName("com.yarin.android.Examples_09_07", ".ExampleBroadcastReceiver"),

PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

}

public void onDisabled(Context context){//当AppWidgetProvider提供的最后一个部件被删除时调用

PackageManager pm = context.getPackageManager();

//用ComponentName来表示应用程序中某个组件的完整名字

pm.setComponentEnabledSetting(new ComponentName("com.yarin.android.Examples_09_07", ".ExampleBroadcastReceiver"),

PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

}

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, String titlePrefix){//更新

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider);//构建RemoteViews对象来对桌面部件进行更新

views.setTextViewText(R.id.appwidget_text, titlePrefix);//更新文本内容,指定布局的组件

appWidgetManager.updateAppWidget(appWidgetId, views);//将RemoteViews的更新传入AppWidget进行更新

}

}

public class ExampleBroadcastReceiver extends BroadcastReceiver{//创建一个BroadcastReceiver类来接收更新的消息,在收到更新消息后就更新这个桌面的Widget组件

public void onReceive(Context context, Intent intent){

//通过BroadcastReceiver来更新AppWidget

String action = intent.getAction();

if (action.equals(Intent.ACTION_TIMEZONE_CHANGED) || action.equals(Intent.ACTION_TIME_CHANGED)){

AppWidgetManager gm = AppWidgetManager.getInstance(context);

ArrayList<Integer> appWidgetIds = new ArrayList<Integer>();

ArrayList<String> texts = new ArrayList<String>();

Activity01.loadAllTitlePrefs(context, appWidgetIds, texts);

final int N = appWidgetIds.size();//更新所有AppWidget

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

ExampleAppWidgetProvider.updateAppWidget(context, gm, appWidgetIds.get(i), texts.get(i));

}

}

}

}

public class Activity01 extends Activity{//此类为android.configure指定的类,用来输入信息

private static final StringPREFS_NAME= "com.yarin.android.Examples_09_07.ExampleAppWidgetProvider";

private static final StringPREF_PREFIX_KEY= "prefix_";

intmAppWidgetId= AppWidgetManager.INVALID_APPWIDGET_ID;

EditTextmAppWidgetPrefix;

public Activity01(){

super();

}

public void onCreate(Bundle icicle){

super.onCreate(icicle);

setResult(RESULT_CANCELED);

setContentView(R.layout.appwidget_configure);

mAppWidgetPrefix = (EditText) findViewById(R.id.appwidget_prefix);

findViewById(R.id.save_button).setOnClickListener(mOnClickListener);

Intent intent = getIntent();

Bundle extras = intent.getExtras();

if (extras != null){

mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);

}

if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID){

finish();

}

mAppWidgetPrefix.setText(loadTitlePref(Activity01.this, mAppWidgetId));

}

View.OnClickListenermOnClickListener= new View.OnClickListener() {

public void onClick(View v){

final Context context = Activity01.this;

String titlePrefix = mAppWidgetPrefix.getText().toString();

saveTitlePref(context, mAppWidgetId, titlePrefix);

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);//取得AppWidgetManager实例

ExampleAppWidgetProvider.updateAppWidget(context, appWidgetManager, mAppWidgetId, titlePrefix);//更新AppWidget

Intent resultValue = new Intent();

resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);

setResult(RESULT_OK, resultValue);

finish();

}

};

static void saveTitlePref(Context context, int appWidgetId, String text){

SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();

prefs.putString(PREF_PREFIX_KEY + appWidgetId, text);

prefs.commit();

}

static String loadTitlePref(Context context, int appWidgetId){

SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);

String prefix = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null);

if (prefix != null){

return prefix;

}else{

return context.getString(R.string.appwidget_prefix_default);

}

}

static void deleteTitlePref(Context context, int appWidgetId){

}

static void loadAllTitlePrefs(Context context, ArrayList<Integer> appWidgetIds, ArrayList<String> texts){

}

}

rew.xml.appwidget_provider.xml//用于描述桌面属性的文件

<?xml version="1.0" encoding="utf-8"?>

<appwidget-provider

xmlns:android="http://schemas.android.com/apk/res/android"

android:minWidth="100dp"//桌面组件的最小宽度和最小高度,其值可以用公式计算 .最小尺寸 = (单元格数*74)-2; 单元格数---期望的单元格数

android:minHeight="50dp"

android:updatePeriodMillis="86400000"//自动更新的时间间隔

android:initialLayout="@layout/appwidget_provider"//界面描述文件

android:configure="com.yarin.android.Examples_09_07.Activity01"//此条代码可选 如果你的Widget需要在启动前需要先启动一个Activity,则需要设定该项为你的Activity

>

</appwidget-provider>

res.layout.appwidget_configure.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

>

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/appwidget_configure_instructions"

/>

<EditText

android:id="@+id/appwidget_prefix"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

/>

<Button

android:id="@+id/save_button"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@android:string/ok"

/>

</LinearLayout>

res.layout.appwidget_provider.xml

<?xml version="1.0" encoding="utf-8"?>

<TextView

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/appwidget_text"

android:textColor="#ff000000"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

/>

AndroidManifest.xml//注册AppWidget、BroadcastReceiver和Activity

<?xml version="1.0" encoding="utf-8"?>

<manifest

xmlns:android="http://schemas.android.com/apk/res/android"

package="com.yarin.android.Examples_09_07"

android:versionCode="1"

android:versionName="1.0">

<application

android:icon="@drawable/icon"

android:label="@string/app_name">

<receiver

android:name=".ExampleAppWidgetProvider">

<meta-data

android:name="android.appwidget.provider"

android:resource="@xml/appwidget_provider" />

<intent-filter>

<action

android:name="android.appwidget.action.APPWIDGET_UPDATE" />

</intent-filter>

</receiver>

<activity

android:name=".Activity01">

<intent-filter>

<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />

</intent-filter>

</activity>

<receiver

android:name=".ExampleBroadcastReceiver"

android:enabled="false">

<intent-filter>

<action android:name="android.intent.ACTION_TIMEZONE_CHANGED" />

<action android:name="android.intent.ACTION_TIME" />

</intent-filter>

</receiver>

</application>

<uses-sdk android:minSdkVersion="5" />

</manifest>

将Widget添加到桌面上,和添加快捷方式一样。

第五部分 Google Map开发

在Android SDK 1.5预装的add-on中提供了一个Map拓展库com.google.android.maps加强了地图功能。这个库的位置"Android SDK路径"\add-ons\google_apis-3\libs 。这个库并不是标准

的Android sdk的内容,可以从这个位置下载,并放到你的SDK中,就可以为你新建的应用或者已有的应用加上地图功能了。

在使用Android Map API之前的准备工作

1、申请一个Android Map API Key步骤:

为了顺利的申请Android Map API Key,必须要准备Google的账号和系统的证明书。一般Google 发布Key都需要Google的账号,Google的账号是通用的,Gmail的账号就可以了

(可到http://www.google.com申请)。当一个应用程序发布时必须要证明书,证明书其实就是MD5. eclipse中测试可以使用Debug版的证明书。

步骤1:找到你的debug.keystore文件

证书的一般路径为:C:\Documents and Settins\当前用户\Local Settions\Application Data\Android\debug.keystore.

如果在Eclipse开发中,便可以通过Windows\Preference\Android\Build.其中Default debug keystore的值便是debug.keystore的路径。

步骤2:取得debug.keystore的MD5值

首先在命令提示符下进入debug.keystore文件所在路径,执行命令:keytool-list-keystore debug.keystore这时会提示你输入密码,这里输入默认的密码"android",即可

获得MD5值。

步骤3:申请Android Map的API Key

打开浏览器,输入网址:http://code.google.com/intl/zh-CN/android/maps-api-signup.html,登陆Google账号,在Google的Android Map API Key申请页面上输入步骤2

得到的MD5认证指纹,选中"I have read and agree with the terms and conditons"选项,然后选中"Generate API Key"按钮,即可以得到申请的API Key.

2、创建基于GoogleAPIs的AVD

在Eclipse中打开AVD管理界面,在"Create AVD"部分的Name处填写AVD的名字,在Target处选择"Google APIs-1.5".点击"Create AVD"完成创建。

3、创建基于Google APIs的工程

同创建一般工程一样,但需要在Build Target处需要选择Google APIs。在运行工程时也需要选择我们刚刚创建的基于Google APIs的AVD来运行。

下面将开始学习如何使用Google API来开发地图应用程序。

Google Map API的使用

Android中定义的包com.google.android.maps中几个重要的类:

MapActivity

这个类是用于显示Google Map的Activity类,它需要连接底层网络。MapActivity是一个抽象类,任何想要显示MapView的activity都需要派生自MapActivity,并且

在其派生类的onCreate()中,创建一个MapView的实例。

MapView

用于显示地图的View组件。它派生自android.view.ViewGroup.它必须和MapActivity配合使用,而且只能被MapActivity创建,这是因为MapView需要通过后台的线程来连接网络或者

文件系统,而这些线程要由MapActivity来管理。

MapController

MapController用于控制地图的移动,缩放等

Overlay

一个可显示于地图之上的可绘制的对象

GeoPoint

一个包含经纬度位置的对象

第一例实现了地图浏览程序

步骤1、创建工程,注意选择Builed Target为"Google APIs"

步骤2、修改AndroidManifest.xml文件

步骤3、创建MapView用于显示地图,即在xml文件中的布局,见例子

步骤4、实现MapActivity,见例子

步骤5、MapController的使用

步骤6、Overlay的使用

AndroidManifest.xml文件

<?xml version="1.0" encoding="utf-8"?>

<manifest

xmlns:android="http://schemas.android.com/apk/res/android"

package="com.yarin.android.Examples_09_03"

android:versionCode="1"

android:versionName="1.0">

<application

android:icon="@drawable/icon"

android:label="@string/app_name">

<uses-library android:name="com.google.android.maps" />//要从网络获取数据,需添加权限

<activity

android:name=".Activity01"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

<uses-permission android:name="android.permission.INTERNET" />

<uses-sdk android:minSdkVersion="5" />

</manifest>

main.xml文件

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<com.google.android.maps.MapView //当然也可以在程序中通过代码 MapView map = new MapView(this,"[Android Maps API Key]");

android:id="@+id/MapView01"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:apiKey="0dYpmIXGIdwiVm-HEpzuUW2fjNYsFQ9EvYir1sg"/>//apiKey即是我们申请的Map API Key

</RelativeLayout>

public class Activity01 extends MapActivity{//实现了地图浏览程序

private MapView mMapView;

private MapController mMapController;

private GeoPoint mGeoPoint;

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mMapView = (MapView) findViewById(R.id.MapView01);

//mMapView.setTraffic(true);//设置为交通模式

mMapView.setSatellite(true);//设置为卫星模式

//mMapView.setStreetView(false);//设置为街景模式

mMapController = mMapView.getController(); //取得MapController对象(控制MapView),用于设置地图显示的地点以及放大倍数

mMapView.setEnabled(true);

mMapView.setClickable(true);

mMapView.setBuiltInZoomControls(true); //设置地图支持缩放

mGeoPoint = new GeoPoint((int) (30.659259 * 1000000), (int) (104.065762 * 1000000));//构建一个GeoPoint来表示地点的经度和纬度,此设置起点为成都

mMapController.animateTo(mGeoPoint); //定位到成都,通过animateTo将地图定位到指定的GeoPoint上

mMapController.setZoom(12); //设置倍数(1-21)

//添加Overlay,用于显示标注信息。

MyLocationOverlay myLocationOverlay = new MyLocationOverlay();

List<Overlay> list = mMapView.getOverlays();

list.add(myLocationOverlay);

}

protected boolean isRouteDisplayed(){

return false;

}

class MyLocationOverlay extends Overlay{//如果需要在地图上标注一下图标文字等信息,可以使用Overlay。

首先要将地图上的经度和纬度转换成屏幕上实际的坐标,才能将信息绘制上去。

public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when){

super.draw(canvas, mapView, shadow);//首先需要实现Overlay中的draw方法才能在地图上绘制信息

Paint paint = new Paint();

Point myScreenCoords = new Point();

mapView.getProjection().toPixels(mGeoPoint, myScreenCoords);// 可以通过toPixels(GeoPoint in,Point out)方法,将经纬度转换成实际屏幕坐标

paint.setStrokeWidth(1);

paint.setARGB(255, 255, 0, 0);

paint.setStyle(Paint.Style.STROKE);

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.home);

canvas.drawBitmap(bmp, myScreenCoords.x, myScreenCoords.y, paint);

canvas.drawText("天府广场", myScreenCoords.x, myScreenCoords.y, paint);

return true;

}

}

}

第二例 实现了定位系统

全球定位系统(Global Positioning System,GPS)又称为全球卫星定位系统,是一个中距离圆型轨道卫星导航系统,它可以为地球表面的绝大部分地区(98%)提供准确的定位、

测速和高精度的时间标准。

Android中关于地理定位系统的API全部位于android.location包中。包括如下几个重要类:

LocationManager 此类包含了访问定位服务的功能,获取最佳定位提供者的功能,临近警报功能也可以借助该类来实现。

LocationProvider 该类是定位提供者的抽象类。定位提供者具备周期性报告设备地理位置的功能。

LocationListener 提供定位信息发生改变时的回调功能。必须先在定位管理器中注册监听器对象。

Criteria 该类使得应用能够通过在LocationProvider中设置的属性来选择合适的定位提供者。

Geocoder 用于处理地理编码和反向地理编码的类。地理编码是指将地址或其他描述转变为经度和纬度,反向地理编码则是将经度和纬度转变为地址或描述语言,其中包含

了两个构造函数,需要传入经度和纬度的坐标。getFromLoction方法可以得到一组关于地址的数组。

此例实现了自动通过定位系统获取用户当前的坐标,然后加载并显示地图,将坐标信息显示在一个TextView

main.xml文件

<?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:id="@+id/TextView01"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"

/>

<com.google.android.maps.MapView

android:id="@+id/MapView01"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:apiKey="0dYpmIXGIdwiVm-HEpzuUW2fjNYsFQ9EvYir1sg"/>

</LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest

xmlns:android="http://schemas.android.com/apk/res/android"

package="com.yarin.android.Examples_09_04"

android:versionCode="1"

android:versionName="1.0">

<application

android:icon="@drawable/icon"

android:label="@string/app_name">

<uses-library android:name="com.google.android.maps" />

<activity

android:name=".Activity01"

android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

<uses-permission android:name="android.permission.INTERNET"/>//要使用API 需添加下例权限

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<uses-sdk android:minSdkVersion="5" />

</manifest>

public class Activity01 extends MapActivity {

public MapController mapController;

public MyLocationOverlay myPosition;

public MapView myMapView;

private static final int ZOOM_IN=Menu.FIRST;

private static final int ZOOM_OUT=Menu.FIRST+1;

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

LocationManager locationManager;//取得LocationManager位置管理器实例

String context=Context.LOCATION_SERVICE;

locationManager=(LocationManager)getSystemService(context);//要使用地理定位,首先需要取得LocationManager的实例,可以通过getSystemService()方法获得。

通过此实例我们可以获得一个位置提供者的列表。在一个真实的手持设备中,这个列表包含了一些GPS服务。

当然我们也可以得到更强大、更精确、不带有其他附件服务的GPS 代码如:

LocationManager locationManager = (LocationManager)getSystemService(Context.LOC-ATION_SERVICE);

myMapView=(MapView)findViewById(R.id.MapView01);

mapController=myMapView.getController();//取得MapController实例,控制地图

//设置显示模式

myMapView.setSatellite(true);

myMapView.setStreetView(true);

myMapView.displayZoomControls(false); //设置缩放控制,这里我们自己实现缩放菜单

//设置使用MyLocationOverlay来绘图

mapController.setZoom(17);

myPosition=new MyLocationOverlay();

List<Overlay> overlays=myMapView.getOverlays();

overlays.add(myPosition);

Criteria criteria =new Criteria();//设置Criteria(服务商)的信息

//经度要求

criteria.setAccuracy(Criteria.ACCURACY_FINE);

criteria.setAltitudeRequired(false);

criteria.setBearingRequired(false);

criteria.setCostAllowed(false);

criteria.setPowerRequirement(Criteria.POWER_LOW);

//取得效果最好的criteria

String provider=locationManager.getBestProvider(criteria, true);

//得到坐标相关的信息

Location location=locationManager.getLastKnownLocation(provider);

updateWithNewLocation(location);//更新坐标

locationManager.requestLocationUpdates(provider, 3000, 0,locationListener); //注册一个周期性的更新,第一参数设置服务提供者,第二个参数设置3000ms更新一次,

重点是第四个参数locationListener用来监听定位信息的改变 所以必须实现以下几个方法:

onLocationChanged(Location location);当坐标改变时触发此函数,如果Provider传进相同坐标,它就

不会触发。

onProviderDisabled(String provider);Provider禁用时触发此函数,比如GPS被关闭

onProviderEnabled(String provider);Provider启用时触发此函数,比如GPS被打开

onStatusChanged(String provider,int status,Bundle extras);Provider的转态在可用,暂时不可用和无服务

状态直接切换时触发此函数

}

private void updateWithNewLocation(Location location) {

String latLongString;

TextView myLocationText = (TextView)findViewById(R.id.TextView01);

String addressString="没有找到地址\n";

if(location!=null){

myPosition.setLocation(location);//为绘制标志的类设置坐标

Double geoLat=location.getLatitude()*1E6; //取得经度和纬度

Double geoLng=location.getLongitude()*1E6;

GeoPoint point=new GeoPoint(geoLat.intValue(),geoLng.intValue()); //将其转换为int型

//定位到指定坐标

mapController.animateTo(point);

double lat=location.getLatitude();

double lng=location.getLongitude();

latLongString="经度:"+lat+"\n纬度:"+lng;

double latitude=location.getLatitude();

double longitude=location.getLongitude();

Geocoder gc=new Geocoder(this,Locale.getDefault()); //更具地理环境来确定编码

try{

//取得地址相关的一些信息\经度、纬度

List<Address> addresses=gc.getFromLocation(latitude, longitude,1);//使用LocationManager和位置提供者进行getFromLocation的调用返回一个Location对象形式的快照

如果调用getFromLocationName方法可能返回一个表示一个地方名称的数据

StringBuilder sb=new StringBuilder();

if(addresses.size()>0){

Address address=addresses.get(0);

for(int i=0;i<address.getMaxAddressLineIndex();i++)

sb.append(address.getAddressLine(i)).append("\n");

sb.append(address.getLocality()).append("\n");

sb.append(address.getPostalCode()).append("\n");

sb.append(address.getCountryName());

addressString=sb.toString();

}

}catch(IOException e){}

}else{

latLongString="没有找到坐标.\n";

}

myLocationText.setText("你当前的坐标如下:\n"+latLongString+"\n"+addressString); //显示

}

private final LocationListener locationListener=new LocationListener(){

public void onLocationChanged(Location location){//当坐标改变时触发此函数

updateWithNewLocation(location);

}

public void onProviderDisabled(String provider){ //Provider被disable时触发此函数,比如GPS被关闭

updateWithNewLocation(null);

}

public void onProviderEnabled(String provider){ //Provider被enable时触发此函数,比如GPS被打开

}

public void onStatusChanged(String provider,int status,Bundle extras){ //Provider的转态在可用、暂时不可用和无服务三个状态直接切换时触发此函数

}

};

protected boolean isRouteDisplayed(){

return false;

}

public boolean onCreateOptionsMenu(Menu menu){ //为应用程序添加菜单

super.onCreateOptionsMenu(menu);

menu.add(0, ZOOM_IN, Menu.NONE, "放大");

menu.add(0, ZOOM_OUT, Menu.NONE, "缩小");

return true;

}

public boolean onOptionsItemSelected(MenuItem item){

super.onOptionsItemSelected(item);

switch (item.getItemId()){

case (ZOOM_IN):

mapController.zoomIn();//放大 通过MapController地图控制器来放大和缩小视图

return true;

case (ZOOM_OUT):

mapController.zoomOut();//缩小

return true;

}

return true;

}

class MyLocationOverlay extends Overlay{

Location mLocation;

public void setLocation(Location location){//在更新坐标时,设置该坐标,一边画图

mLocation = location;

}

public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when){

super.draw(canvas, mapView, shadow);

Paint paint = new Paint();

Point myScreenCoords = new Point();

// 将经纬度转换成实际屏幕坐标

GeoPoint tmpGeoPoint = new GeoPoint((int)(mLocation.getLatitude()*1E6),(int)(mLocation.getLongitude()*1E6));

mapView.getProjection().toPixels(tmpGeoPoint, myScreenCoords);

paint.setStrokeWidth(1);

paint.setARGB(255, 255, 0, 0);

paint.setStyle(Paint.Style.STROKE);

Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.home);

canvas.drawBitmap(bmp, myScreenCoords.x, myScreenCoords.y, paint);

canvas.drawText("Here am I", myScreenCoords.x, myScreenCoords.y, paint);

return true;

}

}

}

如果我们在模拟器上测试,要人为设置一个坐标。可用通过两种方法来设置一个模拟器的坐标值。

第一种方法通过DDMS,我们可以在Eclipse的ADT插件中使用这种方法。步骤:Window---Show View---Emulator Control ---然后手动或通过KML和GPX文件来设置一个坐标

第二种方法使用geo命令,需要telnet到本机的5554端口,然后输入类似于geo fix-121.45356 46.51119 4392这样的命令,后面3个参数代表了经度、纬度和(可选的)海拔。设置

后模拟器上便多出个标志。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: