大家好,我是一个普通的程序员,对软件开发有灰常大的兴趣,今天要和大家分享的是我利用业余时间开发的一款电子书阅读软件。这款软件是以学习为主开发的。在这个系列的文章中,我会将我在开发中遇到的问题,最终的解决方案,以及各种经验之谈分享出来。希望可以与大家共同学习 ,共同进步。同时,这是我注册会员后第一次写自己的文章。希望大家多提建议。我在这里先谢过了。
话不多说,先来几张成品的图片,看下最终效果。大家也好决定是否接着看下去,哈哈!
效果还可以吧,哈哈。
接下来,我讲下整个软件的整体架构流程。
嘎嘎读书的可见页面有如下几个:1书架,2菜单,3随便看看,4分类页,5男生女生标签页,6排行榜,7传统文学推荐,8搜索页,9简介页,10目录页,最后11阅读页。
用到的android原生view控件主要包含 listview gridview 。只要您知道这两种控件的用法,按照我的流程你也一样可以做出这个软件。
按照辅助模块来讲 主要有 阅读模块 下载模块 检测更新模块 。
成品下载地址 :嘎嘎读书
接下来,我们开篇先来介绍一点最简单的内容,即欢迎页面。
欢迎页面 是每个软件几乎都会有的页面,同时欢迎页面也是最简单的开始,故我们从欢迎页面开始。欢迎页面需要一张欢迎图片,随便从网上找一张480*800的图片就可以了,当然最好和我们的主题阅读有些关系。还有不要忘记我们欢迎页面要做的准备工作,一般来说软件的初始化工作都会在欢迎页面完成 ,比如检测网络 sd卡 以及资源的更新,版本的更新等等。我们的欢迎页面比较简单,只检测sd卡上是否存在我们嘎嘎读书的主存文件夹 如果不存在就新建一个文件夹,此文件夹是我们将来 图片和文字等文件存储的文件夹。接下来代码比较简单 直接上了!
package com.prince.gagareader;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo.State;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.prince.gagareader.bean.Const;
import com.prince.gagareader.util.FileUtil;
import com.umeng.analytics.MobclickAgent;
public class GagaReaderBegin extends Activity{
private Handler handler ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.begin);
initHandler();
boolean flag = initAppArgs();
if(flag)
initAD();
}
/**
* 初始化消息解决方案
*/
private void initHandler(){
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1: //正常启动
this.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(GagaReaderBegin.this,
GagaReaderActivity.class);
startActivity(intent);
GagaReaderBegin.this.finish();
}
}, 2000);
break;
default:
break;
}
}
};
}
/**
* 初始化app参数
*/
private boolean initAppArgs(){
loadBoardFile(); //更新榜单文件
return mkAppDirs(); //创建缓存文件夹
}
private boolean mkAppDirs(){
FileUtil fileUtil = FileUtil.getInstance();
Log.e("mkAppDirs", ""+fileUtil.isHaveSize());
if(fileUtil.isHaveSize()){//有剩余空间 就建立文件夹
String rootPath = Environment.getExternalStorageDirectory().getPath();
String appRootPath = rootPath+"/gagaReader";
Const.APP_PHOTO_CACHE= appRootPath+"/photocache";
Const.APP_TEXT_CACHE= appRootPath+"/textcache";
fileUtil.mkdir(appRootPath);
fileUtil.mkdir(Const.APP_PHOTO_CACHE);
fileUtil.mkdir(Const.APP_TEXT_CACHE);
}else{ //没有剩余空间 设置状态为 直接从网络播放 不缓存
// 显示dialog 提示没有sd卡 不能使用
return false;
}
return true;
}
private void loadBoardFile(){
}
/**
* 初始化开屏广告 广告结束后 进入首页
*/
private void initAD(){
String netWorkCate = getNetWorkCate();
if("wifi".equals(netWorkCate)){//出广告之后
sendMessage(1);
}else{
sendMessage(1);
}
}
public void sendMessage(int what){
Message message = new Message();
message.what = what;
handler.sendMessage(message);
}
/*private boolean isOpenNetwork() {
ConnectivityManager connManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if(connManager.getActiveNetworkInfo() != null) {
return connManager.getActiveNetworkInfo().isAvailable();
}
return false;
}*/
private String getNetWorkCate(){
ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
State mobile = conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
if(mobile==State.CONNECTED||mobile==State.CONNECTING)
return "3g";
if(wifi==State.CONNECTED||wifi==State.CONNECTING)
return "wifi";
return "none";
}
public void onResume() {
super.onResume();
MobclickAgent.onResume(this);
}
public void onPause() {
super.onPause();
MobclickAgent.onPause(this);
}
}
下面是对应的布局文件:
相信大家都有android基础,这点简单的代码我就不来解释了。最初的想法是要加一个初始页面的开屏广告,后来觉得以学习为目的先不考虑广告的问题,故没有加入广告代码。同时这个页面需要用到一个fileutil的工具类,我把代码发在下面,这个类以后也会用到,以后就不贴出来了,主要实现一些对文件的操作。
package com.prince.gagareader.util;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.util.EncodingUtils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
public class FileUtil {
private static FileUtil self;
public static FileUtil getInstance(){
if(self==null){
self = new FileUtil();
}
return self;
}
private FileUtil(){}
public void mkdir(String filepath){
File fdir = new File(filepath);
if(!fdir.exists()){
Log.e("mkdir", filepath);
fdir.mkdir();
Log.e("mkdir", fdir.exists()+"");
}
}
public String getFileContent(String path){
return getFileContent(new File(path));
}
public String getFileContent(File f){
StringBuffer sb = new StringBuffer("");
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(f),"utf-8"));
String strBuffer = "";
while((strBuffer=br.readLine())!=null){
sb.append(strBuffer);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
public String getAssetFileContent(Context context,String fileName){
String res="";
try {
InputStream in = context.getResources().getAssets().open(fileName);
int length = in.available();
byte[] buffer = new byte[length];
in.read(buffer);
res = EncodingUtils.getString(buffer, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
return res;
}
public List
getAssetFileContentList(Context context,String fileName){
List
strList=new ArrayList
();
try {
InputStream in = context.getResources().getAssets().open(fileName);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String str = null;
while((str=br.readLine())!=null){
strList.add(str);
}
} catch (IOException e) {
e.printStackTrace();
}
return strList;
}
public String getUrlContent(String url) throws IOException{
StringBuffer sb = new StringBuffer("");
HttpURLConnection conn = null;
BufferedReader br = null;
try {
URL urlHttp = new URL(url);
conn = (HttpURLConnection) urlHttp.openConnection();
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
String str = null;
while((str = br.readLine())!=null){
sb.append(str);
}
} catch (MalformedURLException e) {
e.printStackTrace();
}finally{
if (conn!=null) {
conn.disconnect();
}
if(br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
public Bitmap getBitmapFromFile(File f){
InputStream in = null;
Bitmap bitmap = null;
try {
in = new FileInputStream(f);
bitmap = BitmapFactory.decodeStream(in);
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally{
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}
public void saveUrlContentToFile(String url,String filePath) throws IOException{
if(url==null||!url.startsWith("http:"))return;
checkFileExist(filePath);
File saveFile = new File(filePath);
HttpURLConnection conn = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
try {
URL urlHttp = new URL(url);
conn = (HttpURLConnection) urlHttp.openConnection();
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
bis = new BufferedInputStream(conn.getInputStream());
fos = new FileOutputStream(saveFile);
byte[] bytes = new byte[1024];
int length = 0;
while((length=bis.read(bytes))!=-1){
fos.write(bytes, 0, length);
fos.flush();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
throw e;
}finally{
if(conn!=null){
conn.disconnect();
conn = null;
}
if(bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void checkFileExist(String target) {
File file = new File(target);
if (!file.exists()) {
// 判断文件�?��的路径是否存在,不存在则创建
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try {
Log.e("createFile", file.getPath());
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public boolean isFileExist(String target) {
File file = new File(target);
return file.exists();
}
public long getFreeSize() {
try {
// 取得SDCard当前的状�?
String sDcString = android.os.Environment.getExternalStorageState();
if (sDcString.equals(android.os.Environment.MEDIA_MOUNTED)) {
// 取得sdcard文件路径
File pathFile = android.os.Environment
.getExternalStorageDirectory();
android.os.StatFs statfs = new android.os.StatFs(
pathFile.getPath());
// 获取SDCard上每个block的SIZE
long nBlocSize = statfs.getBlockSize();
// 获取可供程序使用的Block的数�?
long nAvailaBlock = statfs.getAvailableBlocks();
// 计算 SDCard 剩余大小Byte
long nSDFreeSize = nAvailaBlock * nBlocSize;
return nSDFreeSize;
} else {
return -1;
}
} catch (Exception e) {
return -1;
}
}
public boolean isHaveSize() {
if (getFreeSize() < 10485670) {
return false;
} else {
return true;
}
}
public boolean checkFileSize(String filePath,int size){
File f = new File(filePath);
long s=0;
if (f.exists()) {
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
s= fis.available();
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return s==size;
}
public void copyFile(String yuan,String des){
if(yuan==null||"".equals(yuan)||des==null||"".equals(des))return;
File yuanFile = new File(yuan);
File desFile = new File(des);
if(!desFile.exists()){
try {
desFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
FileOutputStream fos = null;
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(yuanFile));
fos = new FileOutputStream(desFile);
byte[] bytes = new byte[1024];
int length = 0;
while((length=bis.read(bytes))!=-1){
fos.write(bytes, 0, length);
fos.flush();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void savePic(Bitmap b, String strFileName) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(strFileName);
if (null != fos) {
b.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.flush();
fos.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void deleteFile(File f){
if(f.isDirectory()){
File[] fs = f.listFiles();
for(File ft:fs){
deleteFile(ft);
}
}else{
f.delete();
}
}
}
好了这第一篇文章就到这里吧,贪多嚼不烂,我会慢慢把所有流程全部讲到,下一篇 我们讲书架~需要知识 listview SharedPreferences 如果请大家先熟悉一下这两个知识点再来看第二篇文章。有问题也可以给我留言。