实验05-android-广播定位
实验目的
1).静态注册:直接在AndroidManifest.xml文件中进行注册。
2).动态注册:动态注册时,无须在AndroidManifest中注册组件。直接在代码中通过调用Context的registerReceiver函数动态注册广播。
静态广播与动态广播的区别
-
动态注册的广播永远要快于静态注册的广播,不管静态注册优先级设置的多高,不管动态注册的优先级有多低,
-
在同一个优先级下,谁先启动的快,谁将先接收到广播
-
动态注册广播不是常驻型广播,也就是广播跟随activity的省命周期(在Activity结束前,移除广播接收器),静态注册是常驻型,也就是说当前应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行,
-
PendingIntent是一个特殊的Intent,主要区别是Intent是立马执行,PendingIntent是待确定的Intent
-
PendingIntent的实际操作上是传入的Intent的操作,使用PendingIntent的目的主要是用于所包含的intent是否满足某些条件
获取PendingIntent有三种方式: -
getActivity(Context context, int requestCode, Intent intent, int flags)
-
getService(Context context, int requestCode, Intent intent, int flags)
-
getBroadCast(Context context, int requestCode, Intent intent, int flags)
PendingIntent的flags参数
- FLAG_CANCEL_CURRENT
- FLAG_UPDATE_CURRENT
- FLAG_NO_CREATE
- FLAG_ONE_SHOT
LocationManager常量可在Intent中携带。
1、LocationManager.KEY_LOCATION_CHANGED
2、LocationManager.KEY_PROVIDER_ENABLED
3、LocationManager.KEY_PROXIMITY_ENTERING
4、LocationManager.KEY_STATUS_CHANGED
1、requestLocationUpdates(provider,time,dis,listenter);
2、 requestLocationUpdates(provider,time,dis,PendingIntent);
新建一个Android项目
AndroidManifest.xml添加权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FIND_LOCATION"/>
<uses-permission android:name="android.permission.BROADCAST_SMS"/>
LocationReceiver.java
package com.example.lu01_week10_brocast;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.util.Log;
public class LocationReceiver extends BroadcastReceiver{
public final String TAG = "LocationReceiver";
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Location location = intent.getParcelableExtra(LocationManager.KEY_LOCATION_CHANGED);
if(location != null){
onLocationReceived(context,location);
}if(intent.hasExtra(LocationManager.KEY_PROVIDER_ENABLED)){
boolean enabled = intent.getBooleanExtra(LocationManager.KEY_PROVIDER_ENABLED, false);
onProviderEnabledChanged(enabled);
}
}
private void onProviderEnabledChanged(boolean enabled) {
Log.v(TAG, "Provider"+(enabled ? "enabled":"disabled"));
}
private void onLocationReceived(Context context, Location location) {
// TODO Auto-generated method stub
Log.v(TAG, this+"Got location from"+location.getProvider()+":"+location.getLatitude()+","+location.getLongitude());
}
}
MainActivity.java
package com.example.lu01_week10_brocast;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity{
String action = "com.example.lu01_week10_brocast";
TextView textView;
Button start,stop;
LocationManager locationManager;
Location mLastlocation;
private BroadcastReceiver mBroadcastReceiver = new LocationReceiver(){
private void onLocationReceived(Location location) {
// TODO Auto-generated method stub
mLastlocation= location;
updateTextView(mLastlocation);
}
private void onProviderEnabledChanged(boolean enabled) {
// Gps服务提供者启动或停止时,消息提示
String toastText = enabled?"gps_enabled":"gps_disabled";
Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_LONG).show();
}
};
protected void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView= (TextView) findViewById(R.id.TextView);
start = (Button) findViewById(R.id.start);
stop= (Button) findViewById(R.id.stop);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
startLocationupdates();
}
});
stop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
stopLocationUpdates();
}
});
};
protected void stopLocationUpdates() {
PendingIntent pi = getLocationPendingIntent(false);
if(pi != null){
locationManager.removeUpdates(pi);
pi.cancel();
textView.setText("stop listener");
Toast.makeText(MainActivity.this, "pi canceled", 2000).show();
}
}
protected void startLocationupdates() {
// 要求LocationManager通过GPS或NETWORK定位装置提供实时的定位数据更新
String bestProvider = locationManager.getBestProvider(getCriteria(), true);
// 获取最近一次地理位置信息,避免用户开启定位时的长时间等待,
Location LastKnownLocation = locationManager.getLastKnownLocation(bestProvider);
updateTextView(LastKnownLocation);
if(LastKnownLocation != null){
broadcastLocation(LastKnownLocation);
}
PendingIntent pi = getLocationPendingIntent(true);
locationManager.requestLocationUpdates(bestProvider, 1, 1, pi);
}
//发送最近一次地理位置信息的广播
private PendingIntent getLocationPendingIntent( boolean shouldCreate) {
Intent broacast = new Intent(action);
int flags = shouldCreate ? 0:PendingIntent.FLAG_NO_CREATE;
return PendingIntent.getBroadcast(MainActivity.this, 0, broacast, PendingIntent.FLAG_CANCEL_CURRENT);
}
private void start() {
// TODO Auto-generated method stub
String bestProvider = locationManager.getBestProvider(getCriteria(),true);
Location location = locationManager.getLastKnownLocation(bestProvider);
updateTextView(location);
if(location != null){
broadcastLocation(location);
}
PendingIntent pi = getLocationPendingIntent();
locationManager.requestLocationUpdates(bestProvider, 0, 0, pi);
}
private PendingIntent getLocationPendingIntent() {
Intent intent = new Intent(action);
PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return null;
}
private void broadcastLocation(Location location) {
Intent intent = new Intent(action);
intent.putExtra(LocationManager.KEY_LOCATION_CHANGED,location );
sendBroadcast(intent);
}
private Criteria getCriteria() {
//设置Criteria
Criteria criteria= new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
// 设置是否要求速度
criteria.setSpeedRequired(false);
// 设置是否允许运营商收费
criteria.setCostAllowed(false);
// 设置是否需要方位消息
criteria.setBearingRequired(false);
// 设置是否需要海拔消息
criteria.setAltitudeRequired(false);
// 设置对电源的需求
criteria.setPowerRequirement(Criteria.POWER_LOW);
return criteria;
}
private void updateTextView(Location location) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
// Address address = getAddress( this,location);
StringBuilder stringBuilder = new StringBuilder();
if(location !=null){
stringBuilder.append("当前经度是:"+location.getLongitude()+"\n");
stringBuilder.append("当前纬度是"+location.getLatitude()+"\n");
stringBuilder.append("当前海拔是"+location.getAltitude()+"\n");
stringBuilder.append("当前时间是"+location.getTime()+"\n");
// stringBuilder.append("当前国家是"+address.getCountryName()+"\n");
// stringBuilder.append("当前省份是"+address.getAdminArea()+"\n");
textView.setText(stringBuilder.toString());
}else {
textView.setTag("location is null");
}
}
private Address getAddress(Context context,Location location) {
// TODO Auto-generated method stub
Geocoder gecoder= new Geocoder(context,Locale.getDefault());
try {
List<Address> lists = gecoder.getFromLocation(location.getLongitude(), location.getLatitude(), 1);
if(lists.size() >0){
return lists.get(0);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
实验结果:
stop后
项目需要注意添加权限,Criteria用于找到合适的地理位置提供者,有三种:gps,移动网络,主动发送位置
静态广播是在配置文件AndroidManifest.xml进行注册,常驻内存的广播
动态广播是在代码里面注册,内存是随着应用程序的结束而结束
PendingIntent是Intent的特殊形式,两者没有太大的变化
本文地址:https://blog.csdn.net/weixin_44123412/article/details/107493316