android基础学习综合实例——天气预报App(基本功能实现)

三、天气预报App基本功能实现
天气预报主要功能就是根据城市的代码,去动态获取当前的天气情况,并且将当前的选择的城市天气信息保存下来(Sharedpreferences).
1、获取JSon天气数据
2、根据android基础学习综合实例——天气预报App中分析的城市代码以及天气代码,保存到数据库中,再根据用户所选择的城市代码,获取对应的天气信息
3、特别注意,因为白天已经过去 ,预报在晚上那次更新的时候白天数据就会为空,即中国气象局的数据在晚上6点以后不会再更新白天的数据信息,在App中必须保存白天的天气信息。

3.1 城市代码数据库建立
(1)省份Province代码数据库:包括省份名称和代码

private static final String CREATE_PROVINCE = "create table Province ("
            + "id integer primary key autoincrement, " 
            + "province_name text, "
            + "province_code text)";

添加对应的数据库操作
1)保存省份实例到数据库中

public void saveProvince(Province province)
{
    if (province != null)
    {
        ContentValues values = new ContentValues();
        values.put("province_name", province.getProvinceName());
        values.put("province_code", province.getProvinceCode());
        db.insert("Province", null, values);
    }
}

2.在数据库中读取全国的所有省份

public List<Province> loadProvices()
{

    List<Province> list = new ArrayList<Province>();
    Cursor cursor = db
    .query("Province", null, null, null, null, null, null);
    if (cursor.moveToFirst())
    {
        do
        {
            Province province = new Province();        province.setId(cursor.getInt(cursor.getColumnIndex("id")));
province.setProvinceName(cursor.getString(cursor
                    .getColumnIndex("province_name")));
            province.setProvinceCode(cursor.getString(cursor
                    .getColumnIndex("province_code")));
            list.add(province);
        } while (cursor.moveToNext());
    }
    return list;
}

(2)市级City代码数据库表建立

private static final String CREATE_CITY = "create table City ("
            + "id integer primary key autoincrement, "
            + "city_name text, "
            + "city_code text, "
            + "province_id integer)";

1.保存City信息到数据库中

public void saveCity(City city)
{
    if (city != null)
    {
        ContentValues values = new ContentValues();
        values.put("city_name", city.getCityName());
        values.put("city_code", city.getCityCode());
        values.put("province_id", city.getProvinceId());
        db.insert("City", null, values);
    }
}

2.根据用户所选的省份id,在数据库中读取对应的市级城市数据

public List<City> loadCity(int provinceId)
{
    List<City> list = new ArrayList<>();
    Cursor cursor = db.query("City", null, "province_id = ?", new String[]
    { String.valueOf(provinceId) }, null, null, null);
    if (cursor.moveToFirst())
    {
        do
        {
            City city = new City();
            city.setId(cursor.getInt(cursor.getColumnIndex("id")));
            city.setCityName(cursor.getString(cursor
                    .getColumnIndex("city_name")));
            city.setCityCode(cursor.getString(cursor
                    .getColumnIndex("city_code")));
            city.setProvinceId(provinceId);
            list.add(city);
        } while (cursor.moveToNext());

    }
    return list;
}

(3)县级County城市代码数据库建立

private static final String CREATE_COUNTY = "create table County ("
            + "id integer primary key autoincrement, "
            + "county_name text, "
            + "county_code text, "
            + "city_id integer)";

1.保存County信息到数据库中

public void saveCounty(County county)
{
    if (county != null)
    {
        ContentValues values = new ContentValues();
        values.put("county_name", county.getCountyName());
        values.put("county_code", county.getCountyCode());
        values.put("city_id", county.getCityId());
        db.insert("County", null, values);
    }

}

2.根据City的id在数据中获取对应的县城数据

public List<County> loadCounties(int cityId)
{
    List<County> list = new ArrayList<County>();
    Cursor cursor = db.query("County", null, "city_id = ?", new String[]
    { String.valueOf(cityId) }, null, null, null);
    if (cursor.moveToFirst())
    {
        do
        {
            County county = new County();
            county.setCityId(cursor.getInt(cursor.getColumnIndex("id")));
            county.setCountyName(cursor.getString(cursor
                    .getColumnIndex("county_name")));
            county.setCountyCode(cursor.getString(cursor
                    .getColumnIndex("county_code")));
            county.setCityId(cityId);
            list.add(county);

        } while (cursor.moveToNext());
    }
    return list;
}

3.2 根据城市代码在线获取城市的天气信息
因为中国气象局返回的数据是JSon格式的,所以我们通过解析JSon格式的数据,获得对应的天气信息。

(1)根据城市代码在线获取天气JSon数据

public static void sendHttpRequest(final String address,
            final HttpCallbackListener listener)
{
    new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            HttpURLConnection connection = null;
            URL url;
            try
            {
                url = new URL(address);
                connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(8000);
                connection.setReadTimeout(8000);
                InputStream in = connection.getInputStream();
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(in,"UTF-8"));//这里用UTF-8是为了防止获取得到的JSON数据中出现中文而导致乱码
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null)
                {
                    response.append(line);
                }
                if (listener != null)
                {
                    // 回调onFinish()方法
                listener.onFinish(response.toString());
                }
                in.close();
            } catch (Exception e)
            {
                if (listener != null) {
                    // 回调onError()方法
                    listener.onError(e);
                }
            } finally{
                if(connection != null){
                    connection.disconnect();
                }
            }

        }
    }).start();

}

其中listener是自定义的一个回调接口,通过回调接口可方便获得返回的天气信息response

public interface HttpCallbackListener
{
    void onFinish(String response);
    void onError(Exception e);
}

以上都是基本准备工作,本APP中主要包括2个Activity:ChooseAreaAcitvity和WeatherActivity。
3.3 ChooseAreaActivity:通过读取Excel获取城市的代码以及名称并显示

public static String loadProvincesInfo(Context context,String xlsPath) throws IOException
{
    if(xlsPath.equals("Area_Excel")){
        StringBuilder provinceInfo= new StringBuilder();
        try{

            InputStream is = context.getAssets().open("areaid_v.xls");
            //ileInputStream fileIn = new FileInputStream(xlsPath);
            // 根据指定的文件输入流导入Excel从而产生Workbook对象
            HSSFWorkbook wb0 = new HSSFWorkbook(is);
            // 获取Excel文档中的第一个表单
            HSSFSheet hssfSheet = wb0.getSheetAt(0);
            // 对Sheet中的每一行进行迭代
            for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++)
            {

                HSSFRow hssfRow = hssfSheet.getRow(rowNum);
                // 如果当前行的行号(从0开始)未达到2(第三行)则从新循环
                if (hssfRow != null)
                {
                    // 创建实体类
                    HSSFCell no = hssfRow.getCell(0);
                    HSSFCell proname = hssfRow.getCell(6);
                    HSSFCell cityname = hssfRow.getCell(4);
                    HSSFCell countyname = hssfRow.getCell(2);
                    /*
                     * String subNo = getValue(no).substring(3, 5);//[3,5)
                     */
                    //返回一行中的省市县的名称已经整个Number 
                    String info = getValue(no) + "|" + getValue(proname) + "|"
                            + getValue(cityname) + "|" + getValue(countyname) + ",";
                    provinceInfo.append(info);
                }
            }
            /*fileIn.close();*/
            is.close();
            return provinceInfo.toString();

        }catch(Exception e){
            Log.d("TAG", "加载excel文件出错");
        }
        return provinceInfo.toString();
    }else{
        Log.d("TAG", "加载excel类型出错,应该为地区类型");
        return null;
    }

}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,关于您的问题,我会尽力回答。在Android中,JNI可以用来与C/C++代码进行交互,我们可以利用JNI来读写SD卡。下面是一个简单的例子: 1. 首先,在您的Java代码中定义native方法: ``` public class MainActivity extends Activity { static { System.loadLibrary("native-lib"); } public native String readFromSDCard(String filePath); public native boolean writeToSDCard(String filePath, String content); } ``` 2. 然后,在您的C/C++代码中实现这些方法: ``` #include <jni.h> #include <string.h> #include <stdio.h> #include <android/log.h> JNIEXPORT jstring JNICALL Java_com_example_myapplication_MainActivity_readFromSDCard(JNIEnv *env, jobject instance, jstring filePath) { const char *path = env->GetStringUTFChars(filePath, 0); FILE *file = fopen(path, "r"); if (file == NULL) { __android_log_print(ANDROID_LOG_ERROR, "JNI", "readFromSDCard: fopen failed"); return NULL; } fseek(file, 0, SEEK_END); long size = ftell(file); fseek(file, 0, SEEK_SET); char *buffer = new char[size + 1]; fread(buffer, 1, size, file); buffer[size] = '\0'; fclose(file); env->ReleaseStringUTFChars(filePath, path); return env->NewStringUTF(buffer); } JNIEXPORT jboolean JNICALL Java_com_example_myapplication_MainActivity_writeToSDCard(JNIEnv *env, jobject instance, jstring filePath, jstring content) { const char *path = env->GetStringUTFChars(filePath, 0); const char *str = env->GetStringUTFChars(content, 0); FILE *file = fopen(path, "w"); if (file == NULL) { __android_log_print(ANDROID_LOG_ERROR, "JNI", "writeToSDCard: fopen failed"); return false; } fwrite(str, 1, strlen(str), file); fclose(file); env->ReleaseStringUTFChars(filePath, path); env->ReleaseStringUTFChars(content, str); return true; } ``` 3. 最后,在您的AndroidManifest.xml文件中添加以下权限: ``` <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> ``` 这样,您就可以在Java代码中调用这些native方法来读写SD卡了。 至于Android NDK的使用实例——增量更新实战,这是一个比较复杂的话题,如果您有相关的需求,可以提出具体的问题,我会尽力为您解答。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只打杂的码农

你的鼓励是对我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值