新应用知识整理-应用中调用Google地图并实现定位
来源:互联网 发布:服装批发软件手机版 编辑:程序博客网 时间:2024/06/04 01:04
前言:
由于国内环境的一些限制,想在国内使用谷歌地图要越过重重困境。
1、应用中调用谷歌地图,要求手机必须安装有最新版本的Google play services应用,并且已经登录了google账号。
这对于国产手机来说有些困难,必须root才能正确安装该应用。
2、要想地图能正常显示出来,手机还有FanQiang。
3、开发者要用自己的google账号到官网申请Google Android Api
申请api的顺序:
(1)使用自己的账号登录https://code.google.com/apis/console/,并创建一个应用
(2)开启这个账号中的android api服务
(3)在命令行中使用命令(keytool -list -alias 昵称 -keystore debug.keystore文件名)(此命令是jdk自带的)获取自己创建的用于给要发布的应用签名的签名文件对于的指纹
(4)根据得到的指纹和应用的包名申请Google map api(Android,也叫凭证)
正文:
先贴出我应用内调用Google地图的代码:
(代码中的定位功能也使用了Google提供的定位服务,免去了我们本地区分使用网络定位还是GPS定位的麻烦。)
import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.graphics.Color;import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.Toast;import com.asiaweiluy.live.v1.Unit.LocationMap.HttpUtil_Map;import com.asiaweiluy.live.v1.MyApplication;import com.asiaweiluy.live.v1.Unit.SharedPreference.ForDataStoreAndRead;import com.asiaweiluy.live.v1.R;import android.app.Dialog;import android.content.ComponentName;import android.content.pm.PackageManager;import android.content.pm.ResolveInfo;import android.location.Location;import android.location.LocationManager;import android.provider.Settings;import android.view.InflateException;import android.widget.AdapterView;import android.widget.BaseAdapter;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;import com.google.android.gms.common.ConnectionResult;import com.google.android.gms.common.GooglePlayServicesUtil;import com.google.android.gms.common.api.GoogleApiClient;import com.google.android.gms.location.LocationListener;import com.google.android.gms.location.LocationRequest;import com.google.android.gms.location.LocationServices;import com.google.android.gms.maps.CameraUpdateFactory;import com.google.android.gms.maps.GoogleMap;import com.google.android.gms.maps.OnMapReadyCallback;import com.google.android.gms.maps.SupportMapFragment;import com.google.android.gms.maps.UiSettings;import com.google.android.gms.maps.model.BitmapDescriptorFactory;import com.google.android.gms.maps.model.Circle;import com.google.android.gms.maps.model.CircleOptions;import com.google.android.gms.maps.model.LatLng;import com.google.android.gms.maps.model.Marker;import com.google.android.gms.maps.model.MarkerOptions;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.net.URISyntaxException;import java.util.ArrayList;import java.util.List;public class LocationFragment extends Fragment implements OnMapReadyCallback,GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { private GoogleApiClient mGoogleApiClient; public static final int SHOW_LOCATION = 0; private LocationManager locationManager; private String provider=null; private Location location=null; private SupportMapFragment mapFragment; private Location mLastLocation; private GoogleMap mMap=null; private Marker melbourne;//自己的位置的marker private Marker selectedMarker;//选中的位置的marker private UiSettings mUiSettings; private ArrayList<Marker> mBranchMarkers=new ArrayList(); private ArrayList<Marker> mAgentMarkers=new ArrayList(); private CheckBox mBranch,mAgency; private static View view; private boolean flag=true;//用于判断是不是第一次调用onCreateView函数加载该fragment界面,如果不是第一次就不需要再进行一些地图中的部件的加载 private List<ResolveInfo> mAllApps; private PackageManager pm; private ListView softlist = null; private Context mContext; private Dialog dialog; private Circle mCircle; private boolean mRequestingLocationUpdates=false,isTheFirstTime=true;//用于判断是不是第一次获取位置更新,用于显示地图 private String Branch_result=null,Agency_result=null; private static final LocationRequest REQUEST = LocationRequest.create()//这里设置我们需要的定位精度等信息 .setInterval(5000) // 5 seconds .setFastestInterval(16) // 16ms = 60fps .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); mContext=getActivity(); AlertDialog.Builder bulider = new AlertDialog.Builder(mContext); int status=GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext);//此状态用于判断手机中Google play services的状态。当前只需要区分手机是否安装了该应用。status==1则表明未安装 switch (status){ case 1://返回1,表明当前没有安装google play services bulider.setMessage(R.string.Google_play_service_missing);//Google Play services missing when getting application info bulider.setCancelable(false); bulider.setPositiveButton(getText(R.string.Login_dialog_sure).toString(), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { getActivity().finish(); } }).show(); break; } setRetainInstance(true); mGoogleApiClient = new GoogleApiClient.Builder(getActivity())//这里设置启用的google服务和我们代码中的监听器 .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); }
@Override public View onCreateView(LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) { if (view != null) { flag=false; ViewGroup parent = (ViewGroup) view.getParent(); if (parent != null) parent.removeView(view); } try { //LayoutInflater作用是将layout的xml布局文件实例化为View类对象。 view = inflater.inflate(R.layout.location_fragment, container, false); mapFragment = (SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map); Log.d("sd", "Fragment is ready ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); mapFragment.getMapAsync(this); } catch (InflateException e) { e.printStackTrace(); //当map api key 不存在时会发生这种异常; /* map is already there, just return view as it is */ } dialog = new Dialog(mContext); dialog.setContentView(R.layout.mapslist); softlist= (ListView) dialog.findViewById(R.id.maps_list);//用于显示应用的列表 dialog.setTitle(R.string.map_choose_app); mBranch= (CheckBox) view.findViewById(R.id.checkBox_branches); mAgency=(CheckBox) view.findViewById(R.id.checkBox_agency); mBranch.setChecked(true); mAgency.setChecked(true); mBranch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { for (int i = 0; i < mBranchMarkers.size(); i++) { mBranchMarkers.get(i).setVisible(true); } } else { for (int i = 0; i < mBranchMarkers.size(); i++) { mBranchMarkers.get(i).setVisible(false); } } } }); mAgency.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { for (int i = 0; i < mAgentMarkers.size(); i++) { mAgentMarkers.get(i).setVisible(true); } } else { for (int i = 0; i < mAgentMarkers.size(); i++) { mAgentMarkers.get(i).setVisible(false); } } } }); locationManager = (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);//获取位置管理器实例,访问位置管理器 List<String> providerList = locationManager.getProviders(true); if (providerList.contains(LocationManager.GPS_PROVIDER)) { } else { // 当没有可用的位置提供器时,弹出Toast提示用户 Toast.makeText(getActivity(),R.string.map_open_GPS, Toast.LENGTH_SHORT).show(); Log.d("sdf", "---------------------No provider -----------------------" + provider); //请用户去打开位置服务 Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivityForResult(intent, 0); }
//下面这一段代码是用来检测手机中安装的地图应用,以打开应用进行路线索引。
Uri mUri = Uri.parse("geo:" + 12.625335 + "," + 104.523967);//打开地图应用列表 Intent it = new Intent(Intent.ACTION_VIEW, mUri); pm=getActivity().getPackageManager(); ComponentName cn =it.resolveActivity(pm); if (cn==null){//如果没有能处理的应用就打开应用商店去寻找 Uri marketUri=Uri.parse("market://search?q=pname:com.myapp.packagename"); Intent marketIntent=new Intent(Intent.ACTION_VIEW).setData(marketUri); if (marketIntent.resolveActivity(pm)!=null){ startActivity(marketIntent); }else Log.d("ds","Market client not available");//如果没有安装应用商店 }else { //如果用户安装有地图应用 mAllApps=pm.queryIntentActivities(it,0); for (ResolveInfo res:mAllApps){//打印一下 Log.d("ds","app info-------------------------"+res.activityInfo.packageName+" "+res.activityInfo.name); } softlist.setAdapter(new MyAdapter(mContext, mAllApps));//用于显示提取到的应用 softlist.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { ResolveInfo res = mAllApps.get(position); //该应用的包名和主Activity String pkg = res.activityInfo.packageName; String cls = res.activityInfo.name; switch (pkg) { case "com.google.android.apps.maps": { Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://ditu.google.cn/maps?f=d&source=s_d&saddr=" + location.getLatitude() + "," + location.getLongitude() + "&daddr=" + selectedMarker.getPosition().latitude + "," + selectedMarker.getPosition().longitude + "&hl=zh")); //如果强制使用googlemap地图客户端打开,就加下面两句 i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); Log.d("ds", " -------google map !!!!!!!!!!!-------------------------"); i.setClassName(pkg, cls); startActivity(i); selectedMarker.hideInfoWindow(); dialog.dismiss(); break;} case "com.baidu.BaiduMap": try { Intent i = Intent.getIntent("intent://map/direction?origin=latlng:"+selectedMarker.getPosition().latitude+","+selectedMarker.getPosition().longitude+"|name:我家&destination=大雁塔&mode=driving®ion=西安&referer=Autohome|GasStation#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end"); Log.d("ds", " -------baidu map !!!!!!!!!!!-------------------------"); Log.e("GasStation", "没有安装百度地图客户端") ; }*/ startActivity(i); //启动调用 selectedMarker.hideInfoWindow(); dialog.dismiss(); break; } catch (URISyntaxException e) { e.printStackTrace(); } default: Toast.makeText(getActivity(),R.string.map_app_support,Toast.LENGTH_SHORT).show(); selectedMarker.hideInfoWindow(); dialog.dismiss(); Log.d("ds", " -------coming soon !!!!!!!!!!!-------------------------"); } } });} return view; }
@Override public void onMapReady(GoogleMap map) {//当地图加载完毕就会调用该函数 Log.d("sd","~~~~~~~~on Map Readyed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); mMap = map; if (flag){ if (location==null){ String filename="LocationFile"; String field="MyLocation_latitude"; String mylocation_latitude= ForDataStoreAndRead.getSharePreString(mContext, filename, field); String field1="MyLocation_longitude"; String mylocation_longitude=ForDataStoreAndRead.getSharePreString(mContext,filename,field1); Log.d("sd","------------保存的位置信息:"); Log.d("sd","------------latitude:"+mylocation_latitude); Log.d("sd","------------longitude:"+mylocation_longitude); map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(Double.parseDouble(mylocation_latitude), Double.parseDouble(mylocation_longitude)), 12)); }else { LatLng myposition=new LatLng(location.getLatitude(), location.getLongitude()); melbourne= mMap.addMarker(new MarkerOptions() .position(myposition) .title(getString(R.string.map_mylocation)) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); mCircle= map.addCircle(new CircleOptions() .center(myposition) .radius(5000) .strokeColor(Color.BLUE) .fillColor(Color.argb(50, 102, 255, 255)).strokeWidth(1)); map.moveCamera(CameraUpdateFactory.newLatLngZoom(myposition, 12)); } map.setMyLocationEnabled(false);//添加我的位置按钮,并使我的位置可见 map.setMyLocationEnabled(true); map.setInfoWindowAdapter(new CustomInfoWindowAdapter()); mUiSettings = mMap.getUiSettings(); mUiSettings.setZoomControlsEnabled(true);//大小伸缩 mUiSettings.setCompassEnabled(true);//指南针 mUiSettings.setMapToolbarEnabled(false);//点击marker时右下角的弹出窗口 new Thread(new Runnable() {//启动线程以获取服务器返回的信息 @Override public void run() { Log.d("sdf","------------------开始测试登录状态-----------------------"); Branch_result= HttpUtil_Map.postJSONtoInternet("这里是服务器的url和传递的JSON数据"); if (Branch_result!=null) { Message message=new Message(); message.what=3; LocationParseHandler.sendMessage(message);} else { Message message=new Message(); message.what=4; LocationParseHandler.sendMessage(message); } } }).start(); new Thread(new Runnable() { @Override public void run() { Log.d("sdf","------------------开始测试登录状态-----------------------"); Agency_result= HttpUtil_Map.postJSONtoInternet("这里是服务器的url和传递的JSON数据"); if (Agency_result!=null) { Message message=new Message(); message.what=1; LocationParseHandler.sendMessage(message); } else { Message message=new Message(); message.what=2; LocationParseHandler.sendMessage(message); } } }).start(); } mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { marker.showInfoWindow(); return false; } }); mMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() { @Override public void onInfoWindowClick(Marker marker) { selectedMarker=marker; dialog.show(); } }); }
//下面的代码是我们实现的接口中的回调函数用于与google服务的连接,以及位置的更新
@Overridepublic void onConnected(Bundle bundle) { Log.d("sd","on Connected ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); startLocationUpdates();//开始更新位置信息 location = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient);}@Overridepublic void onConnectionSuspended(int i) {}@Overridepublic void onConnectionFailed(ConnectionResult connectionResult) {}@Overridepublic void onLocationChanged(Location llocation) { Log.d("sd","~~~~~~~~~~~~~~~on LocationChanged ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); if (isTheFirstTime) { location = llocation; if (mMap!=null) { LatLng myposition = new LatLng(location.getLatitude(), location.getLongitude()); melbourne= mMap.addMarker(new MarkerOptions() .position(myposition) .title(getString(R.string.map_mylocation)) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); mCircle= mMap.addCircle(new CircleOptions() .center(myposition) .radius(5000) .strokeColor(Color.BLUE) .fillColor(Color.argb(50, 102, 255, 255)).strokeWidth(1)); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myposition, 12)); mMap.setMyLocationEnabled(false);//添加我的位置按钮,并使我的位置可见 Log.d("sd", "~~~~~~~~~~~~~~~on LocationChanged ~~~~~~~~~~~~~~~~~~~~~~~~=========isTheFirstTime isTheFirstTime========~~~~~"); mMap.setMyLocationEnabled(true); } isTheFirstTime=false; }else { mCircle.setVisible(false); melbourne.setVisible(false); LatLng myposition = new LatLng(location.getLatitude(), location.getLongitude()); melbourne = mMap.addMarker(new MarkerOptions() .position(myposition) .title(getString(R.string.map_mylocation)) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); mCircle = mMap.addCircle(new CircleOptions() .center(myposition) .radius(5000) .strokeColor(Color.BLUE) .fillColor(Color.argb(50, 102, 255, 255)).strokeWidth(1)); }}
//下面这段代码是在屏幕中央显示的可以启用的第三方map用于列表的adapter的定制
class ViewHolder { ImageView appIcon; TextView tvAppLabel; TextView tvPkgName; public ViewHolder(View view) { this.appIcon = (ImageView) view.findViewById(R.id.img); this.tvAppLabel = (TextView) view.findViewById(R.id.name); this.tvPkgName = (TextView) view.findViewById(R.id.desc); }}class MyAdapter extends BaseAdapter { private Context context; private List<ResolveInfo> resInfo; private ResolveInfo res; private LayoutInflater infater=null; public MyAdapter(Context context, List<ResolveInfo> resInfo) { this.context = context; this.resInfo = resInfo; infater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return resInfo.size(); } @Override public Object getItem(int arg0) { return arg0; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // View view = null; ViewHolder holder = null; if (convertView == null || convertView.getTag() == null) { convertView = infater.inflate(R.layout.soft_row, null); holder = new ViewHolder(convertView); convertView.setTag(holder); } else{ // view = convertView ; holder = (ViewHolder) convertView.getTag() ; } //获取应用程序包名,程序名称,程序图标 res = resInfo.get(position); Log.d("sd","~~~~~~~~~~~~~~~~~-------------------------------------------"); holder.appIcon.setImageDrawable(res.loadIcon(pm)); holder.tvAppLabel.setText(res.loadLabel(pm).toString()); holder.tvPkgName.setText(res.activityInfo.packageName+'\n'+res.activityInfo.name); return convertView; }}
public void onDestroy() { super.onDestroy(); mGoogleApiClient.disconnect(); Log.d("sdf", "----------- onDestroy :---------"); }@Overridepublic void onResume() { super.onResume(); if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect(); if (mGoogleApiClient.isConnected() && !mRequestingLocationUpdates) { startLocationUpdates();//开始更新位置信息 }}@Overridepublic void onPause() { super.onPause(); if (location!=null){//因为定位会比较慢,为了提高用户体验,保存当前用户的位置信息,用于下次启动时使用 String filename="LocationFile"; String field="MyLocation_latitude"; String mylocation_latitude=location.getLatitude()+""; ForDataStoreAndRead.putSharePreString(mContext, filename, field, mylocation_latitude); String field1="MyLocation_longitude"; String mylocation_longitude=location.getLongitude()+""; ForDataStoreAndRead.putSharePreString(mContext, filename, field1, mylocation_longitude); } stopLocationUpdates();//停止更新位置信息}protected void startLocationUpdates() { LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, REQUEST, this); mRequestingLocationUpdates=true;//标志着已经开启位置更新}protected void stopLocationUpdates() { if (mGoogleApiClient.isConnected()) { LocationServices.FusedLocationApi.removeLocationUpdates( mGoogleApiClient, this); mRequestingLocationUpdates = false;//标志着已经开启位置更新 }}
public void parseBranchJSONObject(String json){//对服务器端的分行地址JSON进行解析 try { JSONObject jsonObject =new JSONObject(json); JSONArray jsonArray = jsonObject.getJSONArray("table_data"); for(int i=0;i<jsonArray.length();i++) { JSONObject jsonObject2 = (JSONObject) jsonArray.opt(i); if (!jsonObject2.optString("user_longitude").equals("null")&&!jsonObject2.optString("user_longitude").equals("")){ mBranchMarkers.add(mMap.addMarker(new MarkerOptions() .position(new LatLng(Double.valueOf(jsonObject2.optString("user_longitude")), Double.parseDouble(jsonObject2.optString("user_latitude")))) .title(jsonObject2.optString("user_nickname")) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE)) .snippet("Branch "+"\r\n"+"Phone: "+jsonObject2.optString("user_contact_phone").replace("/","\n ")+"\r\n"+"Location: "+jsonObject2.getString("user_business_location")))); } } } catch (JSONException e) { e.printStackTrace(); }}public void parseAgentJSONObject(String json){//对服务器端的代理地址JSON进行解析 try { JSONObject jsonObject =new JSONObject(json); JSONArray jsonArray = jsonObject.getJSONArray("table_data"); /*Log.d("sd", "----怎么会是null呢------" + jsonArray);*/ for(int i=0;i<jsonArray.length();i++) { JSONObject jsonObject2 = (JSONObject) jsonArray.opt(i); if (!jsonObject2.optString("user_longitude").equals("null")){ mAgentMarkers.add(mMap.addMarker(new MarkerOptions() .position(new LatLng(Double.valueOf(jsonObject2.getString("user_longitude")), Double.parseDouble(jsonObject2.getString("user_latitude")))) .title(jsonObject2.getString("user_nickname")) .snippet("Agent "+"\r\n"+"Phone: "+jsonObject2.getString("user_contact_phone").replace("/", "\n ")+"\r\n"+"Location: "+jsonObject2.getString("user_business_location")))); } } } catch (JSONException e) { e.printStackTrace(); }}
class CustomInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {//自定义的信息窗口布局,因为默认的信息窗详细信息也是单行显示的 private final View mContents; CustomInfoWindowAdapter() {//填充的布局中只是两个textview而已 mContents = getActivity().getLayoutInflater().inflate(R.layout.custom_info_contents, null); } @Override public View getInfoWindow(Marker marker) { return null; } @Override public View getInfoContents(Marker marker) { String title = marker.getTitle(); Log.d("sd", "----222222-------------title------"+title); TextView titleUi = ((TextView) mContents.findViewById(R.id.title)); titleUi.setText(title); String snippet = marker.getSnippet(); TextView snippetUi = ((TextView) mContents.findViewById(R.id.snippet)); snippetUi.setText(snippet); return mContents; } } Handler LocationParseHandler = new Handler(){ public void handleMessage(Message msg){ switch (msg.what){ case 1: parseAgentJSONObject(Agency_result); break; case 2: Toast.makeText(getActivity(),"null result of agent data received from the server", Toast.LENGTH_SHORT).show(); break; case 3: parseBranchJSONObject(Branch_result); break; case 4: Toast.makeText(getActivity(),"null result of Branch data received from the server", Toast.LENGTH_SHORT).show(); break; default: break; } } };}
备注:因为我的地图是显示在fragment中的,这可能会与要直接在activity中显示有些不同。但各种功能的使用是不变的。
看了上面完整的代码,你可能会发现,我们辛辛苦苦申请的google map api用在哪儿?
在android studio中,他被用在AndroidManifest.xml中
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="你的GoogleMapApi key" />
刚接触google地图的开发,写的不好的或不明白的地方还请大家不吝赐教。
- 新应用知识整理-应用中调用Google地图并实现定位
- Google地图应用(一)定位
- 新应用的知识整理-Android studio中应用多语言支持及应用内语言切换的实现
- 新应用的知识整理-Android studio中应用多语言支持及应用内语言切换的实现
- 新应用的知识整理-java代码中完成布局
- 纵谈地图应用中标识定位
- android Google Map地图应用与实现
- ECharts地图应用定位
- iphone中google地图基本应用试验
- google 地图基础应用
- 新应用知识整理-图片的下载、内存软引用与本地缓存的实现
- AngularJS进阶(十九)在AngularJS应用中集成百度地图实现定位功能
- AngularJS进阶(十九)在AngularJS应用中集成百度地图实现定位功能
- 新应用的知识整理-1-启动页
- Android开发--地图与定位应用--申请Google地图服务(API Key)
- ECharts地图应用图片定位
- 调用其他地图应用
- BlackBerry 9850 应用:Google地图
- FZU 1056 扫雷游戏
- jdk目录结构
- final
- 用Notepad++替换记事本程序
- S3C2440裸机之S3C2440GPIO
- 新应用知识整理-应用中调用Google地图并实现定位
- java中给出一个不多于5位数的正整数,要求,第一是求出它是第多少位的,逆序打印出各位数字
- 自定义异常的用法,抛出异常后,代码仍然继续执行。
- cuda
- 安全参透之旅第3章 Webshag工具
- 进程、单线程和多线程
- APP间的调用
- A - Inna and Choose Options
- Linux_LVM&Quota