- 浏览: 21369815 次
- 性别:
- 来自: 杭州
最新评论
-
ZY199266:
配置文件还需要额外的配置ma
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
ZY199266:
我的一访问为什么是 /mavenwebdemo/WEB-I ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
lvgaga:
我又一个问题就是 如果像你的这种形式写。配置文件还需要额外的 ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
lvgaga:
我的一访问为什么是 /mavenwebdemo/WEB-I ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
y1210251848:
你的那个错误应该是项目所使用的目标框架不支持吧
log4net配置(web中使用log4net,把web.config放在单独的文件中)
Android传感器、语音识别、定位系统、Google Map API、快捷方式、widget编程总结及示例
第一部分 传感器
传感器是一种物理装置或生物器官,能够探测、感受外界的信号、物理条件(如:光、热、湿度)或化学组成(如:烟雾),并将探知的信息传递给其他设备或器官。
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个参数代表了经度、纬度和(可选的)海拔。设置
后模拟器上便多出个标志。
相关推荐
Google Map API 使用示例
基于android传感器的应用, 一.可以检测你手机中的有的传感器 二.实现了像Google map方向识别,就是手机向哪个方向,箭头朝你走的反向!
Android google map API例子
写了一些GOOGLE MAP应用,大家分享
申请Android Google Map API key
Google Map API最新版本(V3)代码示例源码和教程,包括了添加地图、在地图上添加和自定义marker的内容、添加曲线和曲线的点击事件等最常用功能。详细教程请见:...
详尽的介绍了google map api 并简单的举了几个例子,能帮助你了解Google map 编程
基于googlemap api 的gps终端和用户管理系统基于googlemap api 的gps终端和用户管理系统基于googlemap api 的gps终端和用户管理系统基于googlemap api 的gps终端和用户管理系统基于googlemap api 的gps终端和用户...
android mapapi 实例 google earth 在android虚拟机上的引用
一、申请google Maps API key(用于开发和debug) 二.Google Map API的使用 三.实例开发
Android应用源码之写的google map api 应用.zip
Android使用Google Map API创建的一个根据经纬度定位的程序. 交流QQ群:1279871
GoogleMap 中文API以及应用示例
Android应用源码之写的google map api 应用.zip项目安卓应用源码下载Android应用源码之写的google map api 应用.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目...
android写的google map api 应用
谷歌地图Google Map API中文开发文档 V3
google map api 实现自定义mark和其移动
使用ArcGIS for Android开发的加载GoogleMap地图。并判断无网络时自动加载本地图片。图片存放在/ArcGIS/samples/tiledcache/下。在有网络时自动存储地图图片。未做容量控制及清空策略。并集成了从ArcGIS Server缓存...
import android.widget.RelativeLayout; import android.widget.Toast; import android.app.Activity; import com.obtk.mapdemo.R; public class MapApiDemoActivity extends Activity implements ...