面向企业应用的Android开发从入门到精通
2015-12-01 19:46
483 查看
安卓开发经验总结
开发环境搭建
现在主流的开发环境就两种,ADT和AndroidStudio。以前因为使用Eclipse的缘故,总是觉得AndroidStudio不好。这也是实情,很多习惯没法改变。但自从看到Google不再维护ADT后,就下决心更改开发工具。使用一段时间,发现其实AndroidStudio还是挺好用的。这也说明一个问题,IT人员有时要敢于突破,不要在老的经验上洋洋自得。AndroidStudio的环境搭建文章多的是,就不一一说明了,只是提到其中一些该注意的点。
1、JavaSDK需要1.7以上
2、AndroidStudio的官网是无法直接访问的,谁叫他姓Google呢。
3、AndroidSDK安装和更新都需要设置代理。在『AndroidSDKManager-Settings』窗口中,在「HTTPProxyServer」和「HTTP
ProxyPort」输入框内填入mirrors.neusoft.edu.cn和80,并且选中「Force
使用常识
1、AndroidStudio和ADT的对比AndroidStudio | ADT |
Project | Workspace |
Module | Project |
1)AVD设置时需要进入高级设置,修改RAM、VMheap、InternalStorage和SDcard大小,避免过大,造成没有内存分配,这样启动不起来。
2)AVD需要安装HAXM(IntelX86EmulatorAccelerator,在AndroidSDK列表的Extras中)。如果本机的硬件加速没有打开,还需要重启机器,进入Bios去打开硬件加速。每台机器的Bios进入有细微差别,搜索一下就知道怎么改了,无非是F1、F2、DEL、F8、F10等这些功能键。
3、使用真机开发的话,android的版本最好在4.2.2以上,为什么呢。不知道,反正我用4.1.2集成信鸽推送时,窗口栏总是不显示推送信息,试了各种手段,都不显示,但实际上是隐藏着的。
开始HelloWorld
环境搭建好后,启动AndroidStudio,就可以开发Android应用了。Android是以JAVA为基础衍生的,那开发人员自然要学习下JAVA了。开始界面
以上功能都可以根据需要使用,但导入ADT工程不是很好用,导入进来,不能直接使用,还要调整半天,不推荐使用,不如自己创建一个新工程来的清晰。
新建工程时,你可以根据需要创建一个默认的Activity,也可以不创建,进入后慢慢增加。不同版本的AndroidBuild-tools自动创建的Activity继承的基类不一样,这也是与时俱进吧,呵呵。
工程管理界面
通过切换视图,可以看到不同的工程目录界面。方便个人的开发习惯。从ADT切换过来,开始还是习惯看Project方式,用用后,感觉Android方式也挺不错。mipmap和drawable
新的Android体系中,mipmap和drawable同时存在,功能都是用于存放图片资源。但mipmap只存放图标资源,并不是别人说的mipmap替换drawable。下面是google的官方描述:drawable/
Forbitmapfiles(PNG,JPEG,orGIF),9-Patchimagefiles,andXMLfilesthatdescribeDrawableshapesorDrawableobjectsthatcontainmultiplestates(normal,pressed,orfocused).SeetheDrawableresourcetype.
mipmap/
Forapplaunchericons.TheAndroidsystemretainstheresourcesinthisfolder(anddensity-specificfolderssuchasmipmap-xxxhdpi)regardlessofthescreenresolutionofthedevicewhereyourappisinstalled.Thisbehaviorallows
launcherappstopickthebestresolutioniconforyourapptodisplayonthehomescreen.Formoreinformationaboutusingthemipmapfolders,seeManagingLauncherIconsasmipmapResources.
常用的功能开发
一个应用,开始就是欢迎页面。如果首次登陆,进入宣传页面;如果不是则进入登陆页(如果已经登陆成功过,则自动进入主页)。当然,如果应用不需要先登录,则可以进入主页。以后就是各个Activity之间的相关跳转,参数传递。这个就根据需要来实现了。当然还有个更重要的功能,就是接收消息通知,并进行处理。
在开发中,我喜欢使用WebView来作为展示的主体。这样的话,业务本身的调整就不太容易影响应用本身,不需要不停的升级来解决业务展示的问题。当然,WebView和Activity之间必然存在参数的传递,这也是要重点解决的。好在有万能的百度,这些都不是问题。
制作欢迎页面
这是应用打开的第一个页面,一般是公司的Logo或产品名称。一般停顿三秒钟后,就会跳转,所以通常都命名为SplashActivity。页面完成自己的初始化后,第一步就是要判断是否首次登陆。这里会用到Android的本地存储功能,本人使用的是SharedPreferences。
//读取SharedPreferences中需要的数据
//使用SharedPreferences来记录程序的使用次数
SharedPreferencespreferences=getSharedPreferences(
SHAREDPREFERENCES_NAME,MODE_PRIVATE);
//取得相应的值,如果没有该值,说明还未写入,用true作为默认值
isFirstIn=preferences.getBoolean("isFirstIn",true);
//判断程序与第几次运行,如果是第一次运行则跳转到引导界面,否则跳转到主界面 if(!isFirstIn){ //使用Handler的postDelayed方法,3秒后执行跳转到MainActivity //获取用户id Stringserver_nonce=(String)GlobalData.getUserId(); if(server_nonce.isEmpty()){ mHandler.sendEmptyMessageDelayed(GO_LOGIN,SPLASH_DELAY_MILLIS); }else{ mHandler.sendEmptyMessageDelayed(GO_MAIN,SPLASH_DELAY_MILLIS); } }else{ mHandler.sendEmptyMessageDelayed(GO_GUIDE,SPLASH_DELAY_MILLIS); }
在宣传页面执行完后,要将isFisrtIn置为true,否则每次进入都要进入宣传页面了。
其中的mHandler用于延时执行相应的跳转:
/** *Handler:跳转到不同界面 */ privateHandlermHandler=newHandler(){ @Override publicvoidhandleMessage(Messagemsg){ switch(msg.what){ caseGO_LOGIN: goLogin(); break; caseGO_GUIDE: goGuide(); break; caseGO_MAIN: goMain(); break; } super.handleMessage(msg); } };
跳转的代码很简单。
Intentintent=newIntent(SplashActivity.this,MainActivity.class);
SplashActivity.this.startActivity(intent); SplashActivity.this.finish();
如果要传递参数,可以设置intent的附属属性,如下:
Bundlebundle=newBundle(); bundle.putString("username","abc"); bundle.putBoolean("isLogin",true); intent.putExtras(bundle);
也可以在洗头中设置全局变量,通过全局变量进行传递。对于用户id,所有Activity都要使用,这种数据使用全局变量更合适。
/** *CreatedbyAdministratoron2015/11/20. */ publicclassGlobalData{ privatestaticStringusername=""; privatestaticStringuserId=""; publicstaticStringgetUserId(){ returnuserId; } publicstaticvoidsetUserId(StringuserId){ GlobalData.userId=userId; } publicstaticStringgetUsername(){ returnusername; } publicstaticvoidsetUsername(Stringusername){ GlobalData.username=username; }
在需要的地方进行读取和设置。
GlobalData.setUserId(userId); GlobalData.setUsername(mUsername);
//获取用户id server_nonce=(String)GlobalData.getUserId();
效果如下:
制作宣传页
宣传页的作用就是通过几张图片或文字,把当前应用的功能或使用方式做个宣传。宣传页使用的主要技术就是PagerAdapter。PagerAdapter主要是viewpager的适配器,而viewPager则也是在android.support.v4扩展包中新添加的一个强大的控件,可以实现控件的滑动效果,比如咱们在软件中常见的广告栏的滑动效果,用viewPager就可以实现。以下代码也是百度提供,直接贴出来,供参考:)。
先建立GuideActivity,实现宣传页面的布局和Adapter的初始化。
publicclassGuideActivityextendsActivityimplementsOnPageChangeListener{ privateViewPagervp; privateViewPagerAdaptervpAdapter; privateList<View>views; //底部小点图片 privateImageView[]dots; //记录当前选中位置 privateintcurrentIndex; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.guide_layout); //初始化页面 initViews(); //初始化底部小点 initDots(); } privatevoidinitViews(){ LayoutInflaterinflater=LayoutInflater.from(this); views=newArrayList<View>(); //初始化引导图片列表 views.add(inflater.inflate(R.layout.what_new_01_layout,null)); views.add(inflater.inflate(R.layout.what_new_02_layout,null)); views.add(inflater.inflate(R.layout.what_new_03_layout,null)); views.add(inflater.inflate(R.layout.what_new_04_layout,null)); //初始化Adapter vpAdapter=newViewPagerAdapter(views,this); vp=(ViewPager)findViewById(R.id.viewpager); vp.setAdapter(vpAdapter); //绑定回调 vp.setOnPageChangeListener(this); } privatevoidinitDots(){ LinearLayoutll=(LinearLayout)findViewById(R.id.ll); dots=newImageView[views.size()]; //循环取得小点图片 for(inti=0;i<views.size();i++){ dots[i]=(ImageView)ll.getChildAt(i); dots[i].setEnabled(true);//都设为灰色 } currentIndex=0; dots[currentIndex].setEnabled(false);//设置为白色,即选中状态 } privatevoidsetCurrentDot(intposition){ if(position<0||position>views.size()-1 ||currentIndex==position){ return; } dots[position].setEnabled(false); dots[currentIndex].setEnabled(true); currentIndex=position; } //当滑动状态改变时调用 @Override publicvoidonPageScrollStateChanged(intarg0){ } //当当前页面被滑动时调用 @Override publicvoidonPageScrolled(intarg0,floatarg1,intarg2){ } //当新的页面被选中时调用 @Override publicvoidonPageSelected(intarg0){ //设置底部小点选中状态 setCurrentDot(arg0); }
<?xmlversion="1.0"encoding="utf-8"?> <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".GuideActivity"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent"/> <LinearLayout android:id="@+id/ll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="24.0dp" android:orientation="horizontal"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="15.0dip" android:src="@drawable/dot"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="15.0dip" android:src="@drawable/dot"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="15.0dip" android:src="@drawable/dot"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:clickable="true" android:padding="15.0dip" android:src="@drawable/dot"/> </LinearLayout> </RelativeLayout>
再建立PagerAdapter,实现页面页面切换、完成初始化设置和进入登陆页。实现PagerAdapter,就需要完成相关方法的重载。
publicclassViewPagerAdapterextendsPagerAdapter{ privatestaticfinalStringSHAREDPREFERENCES_NAME="first_pref"; //界面列表 privateList<View>views; privateActivityactivity; publicViewPagerAdapter(List<View>views,Activityactivity){ this.views=views; this.activity=activity; } //销毁arg1位置的界面 @Override publicvoiddestroyItem(Viewarg0,intarg1,Objectarg2){ ((ViewPager)arg0).removeView(views.get(arg1)); } @Override publicvoidfinishUpdate(Viewarg0){ } //获得当前界面数 @Override publicintgetCount(){ if(views!=null){ returnviews.size(); } return0; } //初始化arg1位置的界面 @Override publicObjectinstantiateItem(Viewarg0,intarg1){ ((ViewPager)arg0).addView(views.get(arg1),0); if(arg1==views.size()-1){ ButtonbtnEnter=(Button)arg0 .findViewById(R.id.btnEnter); btnEnter.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ //设置已经引导 setGuided(); goHome(); } }); } returnviews.get(arg1); } privatevoidgoHome(){ //跳转到登陆页,能够进入宣传页,证明肯定没进行过登陆,不用考虑是否已登录过。 Intentintent=newIntent(activity,LoginActivity.class); activity.startActivity(intent); activity.finish(); } /** *methoddesc:设置已经引导过了,下次启动不用再次引导 */ privatevoidsetGuided(){ SharedPreferencespreferences=activity.getSharedPreferences( SHAREDPREFERENCES_NAME,Context.MODE_PRIVATE); Editoreditor=preferences.edit(); //存入数据 editor.putBoolean("isFirstIn",false); //提交修改 editor.commit(); } //判断是否由对象生成界面 @Override publicbooleanisViewFromObject(Viewarg0,Objectarg1){ return(arg0==arg1); } @Override publicvoidrestoreState(Parcelablearg0,ClassLoaderarg1){ } @Override publicParcelablesaveState(){ returnnull; } @Override publicvoidstartUpdate(Viewarg0){ } }
效果如下:
登陆页面
登陆页面通常会包括两部分内容:1、输入用户名称和密码;2、设置服务器信息。更多的互联网应用还会提供注册页面,让用户自己填写信息,短信确认。当然,这些都要根据自己的实际情况去实现了。我这里实现的是一个非常常规的企业办公软件,就不需要这么复杂了。好了,开工。
AndroidStudio本身就携带LoginActivity模板,基于此模板,增加自己的登陆逻辑即可。
我在该基础上增加的有:
1、是否记住密码
2、调用自己的后台登陆接口实现登陆。
3、登陆成功后,保存用户名称、密码和是否记住密码到本地缓存,并将用户id写入全局变量,供其它Activity使用。
效果如下:
初始化时,读取本地缓存的用户数据,对相关的输入框进行初始化:
privatevoidinit(){ //读取SharedPreferences中需要的数据 //使用SharedPreferences来记录登陆用户参数 SharedPreferencespreferences=getSharedPreferences( LOGIN_PARAMETER,MODE_PRIVATE); //初始化是否记住密码 booleanrememberMe=preferences.getBoolean(REMEMBER_ME,false); if(rememberMe){ mRememberMeView.setChecked(true); } //初始化用户名 Stringusername=preferences.getString(USER_NAME,""); if(!username.isEmpty()){ mUsernameView.setText(username); } //初始化密码 Stringpassword=preferences.getString(PASSWORD,""); if(!password.isEmpty()){ mPasswordView.setText(password); } //初始化服务地址 StringserverAddress=preferences.getString(SERVER_ADDRESS,""); if(!serverAddress.isEmpty()){ mServerAddressView.setText(serverAddress); } }
点击设置按钮,可以查看服务地址:
mSettingView=(TextView)findViewById(R.id.btnSetting); mSettingView.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewview){ if(mServerAddressLayout.getVisibility()==View.VISIBLE){ mServerAddressLayout.setVisibility(View.INVISIBLE); }else{ mServerAddressLayout.setVisibility(View.VISIBLE); } mServerAddressLayout.refreshDrawableState(); } });
点击登陆,执行登陆逻辑,先检查关键信息是否输入,再调用后台接口,实现用户密码验证。这里的关键点就是需要引入HttpClient包,实现HTTP请求和响应。验证通过,则将用户数据写入本地缓存,将用户id写入全局变量:
@Override
protectedBooleandoInBackground(Void...params){
Stringurl="";
if(mServerAddress.startsWith("http://")||mServerAddress.startsWith("https://")){
url=mServerAddress+"/authenticate.m";
}else{
url="http://"+mServerAddress+"/authenticate.m";
}
HttpPosthttpPost=newHttpPost(url);
List<NameValuePair>httpparams=newArrayList<NameValuePair>();
httpparams.add(newBasicNameValuePair("userid",mUsername));
httpparams.add(newBasicNameValuePair("password",mPassword));
try{
httpPost.setEntity(newUrlEncodedFormEntity(httpparams,HTTP.UTF_8));
HttpResponsehttpResponse=newDefaultHttpClient().execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode()==200){
Stringresult=EntityUtils.toString(httpResponse
.getEntity());
JSONObjectresultJson=newJSONObject(result);
StringuserId=resultJson.getJSONArray("body").getJSONObject(0).getString("userId");
GlobalData.setUserId(userId); GlobalData.setUsername(mUsername);
SharedPreferencespreferences=getSharedPreferences(
LOGIN_PARAMETER,Context.MODE_PRIVATE);
SharedPreferences.Editoreditor=preferences.edit();
//存入数据
editor.putString(SERVER_ADDRESS,mServerAddress);
//存入数据
editor.putString(USER_NAME,mUsername);
if(mRememberMe){
//存入数据
editor.putBoolean(REMEMBER_ME,mRememberMe);
//存入数据
editor.putString(PASSWORD,mPassword);
}else{
//存入数据
editor.putBoolean(REMEMBER_ME,false);
//存入数据
editor.putString(PASSWORD,"");
}
//提交修改
editor.commit();
}
}catch(Exceptione){
returnfalse;
}
returntrue;
}
跳转到主页面。
@Override protectedvoidonPostExecute(finalBooleansuccess){ mAuthTask=null; showProgress(false); if(success){ Intentintent=newIntent(LoginActivity.this,MainActivity.class);//从登陆页跳到主页 startActivity(intent); LoginActivity.this.finish(); }else{ mPasswordView.setError(getString(R.string.error_incorrect_password)); mPasswordView.requestFocus(); } }
登陆页开发完成。虽然生成的代码有很多逻辑没理清楚,但不影响使用。
主页
主页是展示业务的地方。这里只提供一个WebView,实现业务网站的嵌套。唯一要做的就是把页面需要的初始化参数传入。参数主要通过Cookie进行传入。
对WebView,还要设置一些参数,以支持JS、支持附件上传和下载。下面对这些关键点进行一一说明。
WebView属性设置:
//WebView WebViewbrowser=(WebView)findViewById(R.id.webView); //设置可自由缩放网页 browser.getSettings().setSupportZoom(true); browser.getSettings().setBuiltInZoomControls(true); //设置支持JS browser.getSettings().setJavaScriptEnabled(true); //如果页面中链接,如果希望点击链接继续在当前browser中响应, //而不是新开Android的系统browser中响应该链接,必须覆盖webview的WebViewClient对象 browser.setWebViewClient(newWebViewClient(){ publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){ //重写此方法表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边 view.loadUrl(url); returntrue; } }); //实现页面上传附件功能 browser.setWebChromeClient(newWebChromeClient(){ //Theundocumentedmagicmethodoverride //Eclipsewillswearatyouifyoutrytoput@Overridehere //ForAndroid3.0+ publicvoidopenFileChooser(ValueCallback<Uri>uploadMsg){ mUploadMessage=uploadMsg; Intenti=newIntent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); MainActivity.this.startActivityForResult(Intent.createChooser(i,"FileChooser"),FILECHOOSER_RESULTCODE); } //ForAndroid3.0+ publicvoidopenFileChooser(ValueCallbackuploadMsg,StringacceptType){ mUploadMessage=uploadMsg; Intenti=newIntent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("*/*"); MainActivity.this.startActivityForResult( Intent.createChooser(i,"FileBrowser"), FILECHOOSER_RESULTCODE); } //ForAndroid4.1 publicvoidopenFileChooser(ValueCallback<Uri>uploadMsg,StringacceptType,Stringcapture){ mUploadMessage=uploadMsg; Intenti=newIntent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); startActivityForResult(Intent.createChooser(i,"FileChooser"),FILECHOOSER_RESULTCODE); } }); //实现页面下载附件功能,基于浏览器实现 browser.setDownloadListener(newDownloadListener(){ @Override publicvoidonDownloadStart(Stringurl,StringuserAgent,StringcontentDisposition,Stringmimetype, longcontentLength){ Uriuri=Uri.parse(url); Intentintent=newIntent(Intent.ACTION_VIEW,uri); startActivity(intent); } });
同时还要创建相关的方法以支持属性设置:
@Override protectedvoidonActivityResult(intrequestCode,intresultCode, Intentintent){ if(requestCode==FILECHOOSER_RESULTCODE){ if(null==mUploadMessage)return; Uriresult=intent==null||resultCode!=RESULT_OK?null :intent.getData(); mUploadMessage.onReceiveValue(result); mUploadMessage=null; } }
Cookie同步,通常就是同步用户id,在打开相应Url的时候调用即可:
synCookies(getBaseContext(),url,"userId="+userId);
browser.loadUrl(url);
/**
*同步一下cookie
*/
publicstaticvoidsynCookies(Contextcontext,Stringurl,Stringvalue){
CookieManagercookieManager=CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.setCookie(url,value);//cookies是在HttpClient中获得的cookie
Log.d("cookie",cookieManager.getCookie(url));
}
如果需要在每次打开页面的时候都重新刷新一下WebView,需要增加以下代码:
@Override
protectedvoidonNewIntent(Intentintent){
super.onNewIntent(intent);
setIntent(intent);//必须要调用这句
openUrl();
}
效果如下:
Android还有一个更强大的功能就是能够实现WebView中的JS调用JAVA功能,JAVA也可以调用JS方法,只是配置有点复杂,目前没感觉特别有用,没有去深究,有兴趣的就去问百度了,呵呵。
消息通知
世面上有很多免费和收费的消息推送服务,接触到的有极光推送、个推、百度推送、腾讯信鸽推送。极光和个推都是有收费版的,这样的不太放心,于是在百度和腾讯中选。发现腾讯有个好的就是可以按别名推送,刚好满足使用账号推送的需求,于是选择了他。集成腾讯信鸽推送其实很简单,按照他的Demo或文档描述配置即可,这里只强调一下关键的用法,比如参数传递。
服务端只要引入他的XingeApp.jar,然后再需要的地方初始化,并发送消息即可。其中的accessId和secret是在注册应用时自动生成的唯一信息。可以进入信鸽推送管理平台获取。
intaccessId=21001*****;
Stringsecret="**************";
XingeAppxinge=newXingeApp(accessId,secret);
。。。。。。
Messagemessage=newMessage();
message.setExpireTime(86400);
message.setTitle(attention.getTitle());
message.setContent(content);
message.setType(Message.TYPE_NOTIFICATION);
//传递自定义参数
Map<String,Object>mapValue=newHashMap<String,Object>();
mapValue.put("relativeId",attention.getRelativeId());
mapValue.put("messageType",attention.getMessageType);
message.setCustom(mapValue);
ClickActionaction=newClickAction();
action.setActionType(ClickAction.TYPE_ACTIVITY);
action.setActivity("net.qiangqi.oa.MessageActivity");
message.setAction(action);
org.json.JSONObjectret=xinge.pushAccountList(0,userIds,message);
服务端集成就这么简单。
Android应用集成也很简单,参考Demo即可。但Demo没有涉及参数的传递,这里着重描述一下。
信鸽客户端是要在Activity的onStart或onRestart才能截获。开始的时候,我把截获的代码放在onCreate中,死活也得不到参数,也是在度娘的帮助下,才发现这个问题。信鸽的Demo应该要补充下这个信息才好。
1、在onCreate中对信鸽客户端进行注册。这里也要注意,不要每次都进行注册,最好记录一下注册的状态,如果已经注册,则不要重复发起注册,一方面浪费时间,另一方面会造成现有消息因为注册而被销毁。
2、在onStart中进行消息参数截获,并处理。其中的click.getCustomContent()中的值就是服务器端message.setCustom(mapValue)中设置的
@Override
protectedvoidonStart(){
super.onStart();
//读取SharedPreferences中需要的数据
//使用SharedPreferences来记录登陆用户参数
SharedPreferencespreferences=getSharedPreferences(
LOGIN_PARAMETER,MODE_PRIVATE);
//获取服务器地址
StringmServerAddress=preferences.getString(SERVER_ADDRESS,"");
Stringurl="http://"+mServerAddress+"/index.html";
//获取用户id
userId=(String)GlobalData.getUserId();
//WebView
WebViewbrowser=(WebView)findViewById(R.id.webView);
booleandetailed=false;
synCookies(getBaseContext(),url,"userId="+");
//获取推送消息附属信息
XGPushClickedResultclick=XGPushManager.onActivityStarted(this);
if(click!=null){
StringcustomContent=click.getCustomContent();
//获取自定义key-value
if(customContent!=null&&customContent.length()!=0){
try{
JSONObjectjson=newJSONObject(customContent);
if(json.get("messageType")!=null&&json.get("relativeId")!=null){
indexUrl=indexUrl
+"?messageType="+json.getString("messageType")
+"&relateId="+json.getString("relativeId");
browser.loadUrl(indexUrl);
detailed=true;
}
}catch(JSONExceptione){
e.printStackTrace();
}
}
}
if(!detailed){
Intentintent=newIntent(MessageActivity.this,MainActivity.class);//从欢迎页跳到登陆页
startActivity(intent);
MessageActivity.this.finish();
}
}
大功告成。
这里有个需要注意的地方是:信鸽推送应该不支持低版本的Anroid。开始我在三星Notes2上开发测试,看到消息推送到手机了,但在窗口栏中死活不显示,曾经偶尔看到闪了这么一下,于是各种怀疑,各种假设,都没有成功。最后换了个手机,消息马上显示出来了。这个教训是用了几天时间发现的,说起来有点丢人,大家千万注意:)。
总结
到此为止,一个有点样子的Android应用就开发出来了,没有想象的这么难。对于企业级的APP,内嵌网页我觉得是比较合适的,因为业务在不停的调整,不能因为这个去不停的升级客户端,而且也没法让一个客户端去支持多个企业。做完了客户端,再写写这个总结,还是颇有收获,希望对大家有所帮助。
相关文章推荐
- android socket简单编程(java在PC本地创建服务器)
- 【Android Studio】制作启动画面Splash Screen
- android欢迎界面并执行任务
- Android之Fragment(二)
- Android知识总结:Universal-Imageloader学习笔记2 主业务流程源码分析
- 关于Android中RSA数字签名的理解及使用
- Android:代码修改layout_marginBottom的属性
- Android ListView分页加载(服务端+android端)De
- 光标 与 输入法 之 android:imeOptions属性
- Android 虚线分割线
- 解决一些android studio 中的编码问题
- Android中几种常用的定时器和延时方法
- Android的按钮单击事件及监听器的实现方式
- ubuntu下Qt之android环境配置以及一些常见问题解决
- android坐标
- Android SDK 开发范例大全 ---3.8手机页面的转换
- Android 换肤功能的实现(Apk插件方式)
- 将Eclipse代码导入到AndroidStudio的两种方式
- android之解析json数据格式详解
- Android Context原理与使用的总结