刚刚完成了一个课表程序。刚开始学android,得把这些记录下来,方便以后查看。
我要做的东西是把学校服务器的课程表抓取下来,然后再在本机显示。这个课表程序可以对某节课进行编辑删除,可以设置闹钟。
1.读取学校教务处网页:
用android自带的httpclient来获取网页。httpclient非常强大,它可以模拟一个浏览器来对服务器进行访问。对于不需要进行验证的网页,只要用get方法就可以取得网页,而对于需要验证的网页就得用post方法。(看到一篇关于http协议的文章,很好:http://blog.csdn.net/gueter/article/details/1524447)
但是有时候你也许服务器也不会理你,因为你的http报头并没有满足它的要求。这时候怎么办呢?给个提示:去研究一下http协议。
还有,把网页抓取下来后的html还需要进行解析才行。由于我的目标网页结构简单,我就自己写了一个简单的解析操作。
有人问我如果目标网页是有框架的该怎么抓取呢?我发一张图你就明白了
这是CSDN的论坛页面,它是有框架的,左边页面和右边页面的网址不一样。所以你只需要填入你想要的页面的网址就可以了。
2.接下来就是表格显示
由于刚开始学,很笨,就用一个个的textview来拼成了课表,不过这样挺好的,可以让我后期做的时候方便一些。效果是这样的:
所有的东西都是textview,最左边的一列(第几节那列)是不随着右边的滑动而滑动的,这样浏览的时候更方便。下面是布局的嵌套关系
3.进度条对话框和线程
当响应操作时间比较长的时候就需要进度条对话框了。
其实说到它我最想记录的还是线程。开启了进度条对话框后常常与之对应的就是线程了。用以下的方法就可以开启一个线程
-
-
newThread(){
-
publicvoidrun(){
-
try{
-
-
-
}catch(InterruptedExceptione){
-
handler.sendEmptyMessage(0x222);
-
}catch(Exceptione){
-
-
handler.sendEmptyMessage(0x333);
-
}finally{
-
-
pdialog.dismiss();
-
}
-
}
-
}.start();
4.handler
上面代码里的handler.sendEmptyMessage给已经定义好的handler发消息,这样能够在线程执行过程中通知线程的执行状态,这样可根据发回来的消息来进行下一步操作。很有用!
-
Handlerhandler=newHandler()
-
{
-
@Override
-
publicvoidhandleMessage(Messagemsg)
-
{
-
if(msg.what==0x111)
-
{
-
}
-
if(msg.what==0x333)
-
{
-
}
-
}
-
};
用msg.what取得线程发回来的消息。
5.DES加密
有时候要加密用户的信息来存储。可以参考下面的代码。(这是从别人那儿看来的,出处找不到了,真不好意思!)
-
publicclassEncrypt{
-
publicstaticStringencrypt(Stringtxt,Stringkey)
-
throwsInvalidKeySpecException,InvalidKeyException,
-
NoSuchPaddingException,IllegalBlockSizeException,
-
BadPaddingException{
-
StringBuffersb=newStringBuffer();
-
DESKeySpecdesKeySpec=newDESKeySpec(key.getBytes());
-
SecretKeyFactoryskeyFactory=null;
-
Ciphercipher=null;
-
try{
-
skeyFactory=SecretKeyFactory.getInstance("DES");
-
cipher=Cipher.getInstance("DES");
-
}catch(NoSuchAlgorithmExceptione){
-
e.printStackTrace();
-
}
-
SecretKeydeskey=skeyFactory.generateSecret(desKeySpec);
-
cipher.init(Cipher.ENCRYPT_MODE,deskey);
-
byte[]cipherText=cipher.doFinal(txt.getBytes());
-
for(intn=0;n<cipherText.length;n++){
-
Stringstmp=(java.lang.Integer.toHexString(cipherText[n]&0XFF));
-
-
if(stmp.length()==1){
-
sb.append("0"+stmp);
-
}else{
-
sb.append(stmp);
-
}
-
}
-
returnsb.toString();
-
}
-
publicstaticStringdecrypt(Stringtxt,Stringkey)
-
throwsInvalidKeyException,InvalidKeySpecException,
-
NoSuchPaddingException,IllegalBlockSizeException,
-
BadPaddingException{
-
DESKeySpecdesKeySpec=newDESKeySpec(key.getBytes());
-
SecretKeyFactoryskeyFactory=null;
-
Ciphercipher=null;
-
try{
-
skeyFactory=SecretKeyFactory.getInstance("DES");
-
cipher=Cipher.getInstance("DES");
-
}catch(NoSuchAlgorithmExceptione){
-
e.printStackTrace();
-
}
-
SecretKeydeskey=skeyFactory.generateSecret(desKeySpec);
-
cipher.init(Cipher.DECRYPT_MODE,deskey);
-
byte[]btxts=newbyte[txt.length()/2];
-
for(inti=0,count=txt.length();i<count;i+=2){
-
btxts[i/2]=(byte)Integer.parseInt(txt.substring(i,i+2),16);
-
}
-
return(newString(cipher.doFinal(btxts)));
-
}
-
}
包括了加密和解密。但要注意使用相同的Key
6.文件操作
文件操作一google一大堆,但有的用不了,中文会出现乱码,我是用InputStreamReader和BufferedReader来读取才能读出中文的
-
InputStreamReaderisr=newInputStreamReader(newFileInputStream(file),"utf-8");
-
BufferedReaderbr=newBufferedReader(isr);
接下来只要用br.readLine()就可以按行读取了。
7.Activity界面通信
刚开始还没学会activity,显示与切换界面全用的是setContentView()。后来果然有很多的不方便啊,比如界面要经常切换而且它们之间要传递信息的时候写的代码就很乱。和我一样懒的还是好好学activity吧。来记录一个很有用的:我的MainActivity需要传递信息给UpdateActivity,后者也要返回信息。
在MainActivity里这么写:
-
Bundledata=newBundle();
-
data.putString("info",要传的信息);
-
Intentintent=newIntent();
-
intent.setClass(MainActivity.this,UpdateActivity.class)
-
intent.putExtras(data);
-
startActivityForResult(intent,0);
在UpdateActivity里这么写:
-
Stringstr=this.getIntent().getExtras().getString("info");
-
-
Intentintent=getIntent();
-
Bundlebundle=newBundle();
-
bundle.putString("backinfo",回传的消息);
-
intent.putExtras(bundle);
-
setResult(RESULT_OK,intent);
-
finish();
在MainActivity里重写接收回传信息的方法
-
-
@Override
-
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata)
-
{
-
switch(resultCode)
-
{
-
-
caseRESULT_OK:
-
Bundlebunde=data.getExtras();
-
Stringback=bunde.getString("lessoninfo");
-
}
-
}
8.由资源id对应的名称获得资源id
我之间也说过我的表格全是用的textview来做的,像这样android:id="@+id/tv1"是我第一个textview。那么当我要操作那么多个的textview时不可能一个个地写它们对应的事件吧。所以用到了下面的方法。
//这个方法可以根据id对应的string返回在R.java里记录资源的id
-
Resourcesres=getResources();
-
intj=res.getIdentifier("tv"+String.valueOf(i),"id",getPackageName());
再啰嗦一下,就是有tv1,tv2,tv3,……上面的i就可以是1,2,3
9.设置闹钟
可参考:http://blog.csdn.net/jeethongfei/article/details/6767826
我要说的是怎么设置多个闹钟。关键是PendingIntent pi=PendingIntent.getActivity(MainActivity.this, i, intent, 0);里的i。把i设置为不同的值就可以设置不同的闹钟了。只需设置这个地方而已!不需其它!
-
Intentintent=newIntent(MainActivity.this,AlarmActivity.class);
-
Bundledata=newBundle();
-
PendingIntentpi=PendingIntent.getActivity(MainActivity.this,i,intent,0);
-
ring=(AlarmManager)getSystemService(Service.ALARM_SERVICE);
-
ring.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),600*100*60*24*7,pi);
10.一设置闹钟就会响的问题
如果你设置响铃的时间是在当前时间之前,那你一设置好闹钟就会响。可以按照下面的设置
-
Calendarc=Calendar.getInstance();
-
intcweek=c.get(Calendar.DAY_OF_WEEK);
-
intchour=c.get(Calendar.HOUR_OF_DAY);
-
intcminute=c.get(Calendar.MINUTE);
-
-
-
if(week<cweek||(week==cweek&&(hour<chour||minute<cminute)))
-
{
-
ring.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis()+600*100*60*24*7,600*100*60*24*7,pi);
-
}
-
else
-
{
-
ring.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),600*100*60*24*7,pi);
-
}
ring是AlarmManager的实例,calendar是Calendar实例。week是想要设置的是星期几,hour是想要设置的小时,minute是分钟。要注意用get(Calendar.DAY_OF_WEEK)返回的星期天是1,星期一是2,依此类推。600*100*60*24*7,是一个星期的时间。
那为什么要像上面那么设置呢?如果今天是星期六(cweek就是7),想要设置的是星期1响(week就是2),那么如果用ring.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),600*100*60*24*7,pi);这样能够让下个星期一响。如果用ring.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis()+600*100*60*24*7,600*100*60*24*7,pi); 这样会让下下个星期一响,不符合设想。如果想要让下个星期五(week就是6)响,用用ring.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),600*100*60*24*7,pi);闹钟会立即响,而用ring.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis()+600*100*60*24*7,600*100*60*24*7,pi);就能让下个星期五响。有点明白了吧,得好好想想。
11.一定要注意!
比较两个字符串一定要用equals方法。String的split方法不会修改它本身,而是产生一个新的修改过的字符串!当要用系统资源时要加上权限!记得在AndroidManifest.xml中注册Activity!
由于涉及一些信息,我就不 上传源码了。
-
<pre></pre>
-
<pre></pre>
-
<pre></pre>
分享到:
相关推荐
Python项目案例开发从入门到实战源代码第6章 爬虫应用——抓取百度图片
基本操作 鼠标右击模型,抓取该模型,再次右击空地,放下模型到该点。
Android log抓取工具,包含 logcat bugreport trace等
Android Jsoup 爬虫协议抓取网页信息
jsoup抓取网页内容volley下载图片
java抓取网页数据实现
使用jsoup 抓取虾米网站的歌曲数据,包括专辑图片 ,歌词,歌曲路径等信息
我测试了,好使的。 android获取数据,这个网页可以是aspx,也可以是php。简单的实现少量数据传递。手机获取网页数据,adroid获取C#页面数据传递也是都可以。
java简单的抓取网页内容的程序java简单的抓取网页内容的程序java简单的抓取网页内容的程序java简单的抓取网页内容的程序java简单的抓取网页内容的程序java简单的抓取网页内容的程序java简单的抓取网页内容的程序java...
android网页抓取一个Demo,抓取的是新浪新闻。 适合有一定网络和编程基础的新手。
getcsdnlistview 【Android 我的博客APP】1.抓取博客首页文章列表内容——网页数据抓取
不使用Eclipse 和 Android Studio,也可以查看安卓日志的软件。告别adb命令行。 注意 该项目是基于Java环境开发,请自行安装Java环境。
网站爬虫——图片抓取小工具
RPA之家全套视频教程,想系统学习RPA的,可以下载该资源学习。在学习的过程中,如果碰到任何问题,也可以在评论区里面交流。
自动抓取网页视频,批量下载m3u8视频ts文件,并自动合成一个MP4格式视频文件
使用bat脚本编写,简单,点击就能用 不要安装各种软件环境
一个经典的网页爬虫工具,可以用来动态抓取网页!
这个demo是用c#语音开发的运用正则抓取网页数据,可以用来学习、借鉴。
C# 抓取网页内容帮助方法,能投通过标签自动匹配想要输出的内容
自动抓取网页内容自动抓取网页内容自动抓取网页内容自动抓取网页内容自动抓取网页内容自动抓取网页内容