首先呢,我先做一下广告吧,我们团队是:IMUDGES(内蒙古大学精英开发者联盟 )大家有什么好的想法可以和我们交流,给我的博客留言!
在我几天不断的努力下,记事本的后台操作基本搞定了,现在和大家就一起分享一下,首先,记事本应该有增、删、该的功能吧,今天我就和大家一起看看这些功能怎么实现,当然这是我的个人思路,如果大家有更好的想法可以给我留言,一起讨论讨论;
1、首先,新建一个;
好,第一个记事写好了,然后就开始保存了。我是这样做的,保存的时候把我笔记的题目放在一个<li></li>标签里面,然后把写好这个日记的日期也取下来,我看了一下我手机上的记事本,就有这个功能,所以我也加上了这个功能。先看看效果。
这样就有了以上的界面,那么里面的代码怎么写的呢,我先给大家说一说这个日期是怎么弄的。看代码:
var today = new Date(); var year = today.getFullYear(); var month = (today.getMonth() + 1) < 10 ? '0' + (today.getMonth() + 1) : (today.getMonth() + 1); var day = (today.getDate()) < 10 ? '0' + (today.getDate()) : (today.getDate()); var hours = (today.getHours()) < 10 ? '0' + (today.getHours()) : (today.getHours()); var minutes = (today.getMinutes()) < 10 ? '0' + (today.getMinutes()) : (today.getMinutes()); var seconds = (today.getSeconds()) < 10 ? '0' + (today.getSeconds()) : (today.getSeconds()); date1 = year + "-" + month + "-" + today.getDate() + " " + hours + ':' + minutes + ':' + seconds;
这样date1这样一个变量就是一个时间的字符串,把这个字符串的值穿到<li></li>这个标签里面,用jQuery做这些任务。
2、然后大家可以点击那个<li></li>标签,就是那个“我的第一个日记”,然后就是进入了你的写的内容了。看效果:
这里的内容我都设置成了只读的模式,目前大家是不能改动这个记事内容的,其实上一节的html5的代码中就有设置的,大家可以返回去看看那个代码。
3、大家可以重新编辑这个记事或删除这个记事,按选项会弹出一个对话框可以进行选择删除还是编辑。看效果:
如果大家选择编辑的话,上面写的内容就变成可写的了,大家就可以改动了。
大家应该能看出来吧,我的标题也变化了,上面显示的时间是你做完修改的时间!再然后看看删除:
这样就删除功能也有了。好吧,效果都看完了,说说代码吧。
var today = new Date();
var year = today.getFullYear();
var month = (today.getMonth() + 1) < 10 ? '0' + (today.getMonth() + 1) : (today.getMonth() + 1);
var day = (today.getDate()) < 10 ? '0' + (today.getDate()) : (today.getDate());
var hours = (today.getHours()) < 10 ? '0' + (today.getHours()) : (today.getHours());
var minutes = (today.getMinutes()) < 10 ? '0' + (today.getMinutes()) : (today.getMinutes());
var seconds = (today.getSeconds()) < 10 ? '0' + (today.getSeconds()) : (today.getSeconds());
date1 = year + "-" + month + "-" + today.getDate() + " " + hours + ':' + minutes + ':' + seconds;
var moban = $("#time");
$(function(){
var title;
var content;
$("#save").click(function(){
title=$("#texttheme").val();
content = $("#textcontent").val();
if(title=="")
alert("theme is not null!");
else{
$.mobile.changePage("#page1","slideup");
$("#time").append(date1);
$("#neirong").append(title);
$("#time").slideDown("fast");
$("#content").slideDown("fast");
document.getElementById("texttheme").value="";
document.getElementById("textcontent").value="";
}});
$("#neirong").click(function(){
document.getElementById("opentexttheme").value=title;
document.getElementById("opentextcontent").value=content;
});
$("#bianji").click(function(){
$.mobile.changePage("#page2","slidedown");
document.getElementById("texttheme").value=title;
document.getElementById("textcontent").value=content;
$("#save").click(function(){
var today = new Date();
var year = today.getFullYear();
var month = (today.getMonth() + 1) < 10 ? '0' + (today.getMonth() + 1) : (today.getMonth() + 1);
var day = (today.getDate()) < 10 ? '0' + (today.getDate()) : (today.getDate());
var hours = (today.getHours()) < 10 ? '0' + (today.getHours()) : (today.getHours());
var minutes = (today.getMinutes()) < 10 ? '0' + (today.getMinutes()) : (today.getMinutes());
var seconds = (today.getSeconds()) < 10 ? '0' + (today.getSeconds()) : (today.getSeconds());
date1 = year + "-" + month + "-" + today.getDate() + " " + hours + ':' + minutes + ':' + seconds;
$("#time").empty();
$("#neirong").empty();
$("#time").append(date1);
$("#neirong").append(title);
});
});
$("#shanchu").click(function(){
$.mobile.changePage("#page1","slidedown");
$("#time").css("display","none");
$("#content").css("display","none");
title="";
content="";
});
});
说实话,我这人比较懒啊,就这样把整个的js文件的代码都靠过来了,本人习惯不是太好,反正能看懂的就多提意见,看不懂的给我留言。有了这个还有css里面的东西,写的不是很多,就是把一开始的显示的时间和题目的那个标签先影藏了,然后要用到的时候就把它给弄出来!看css代码吧:
#time{
display: none;
}
#content{
display: none;
}
就这么三四行,就是先把不该显示的东西先给影藏了!不过这就是一个练习吧,做的虽然不是很强大,但是有什么不足的地方还希望大牛指出,代码我就不一行一行解释了,不是很难,就是jQuery中的一些api。不懂的可以查一查jQuery的api。是在不懂的就直接把代码拷过去就行了。需要提醒的是,最好在google的chrome中运行,这个浏览器支持html5支持的比较好!好吧,没了,有什么小的作品再和大家分享!
在jquerymobile中我们如果使用网格去布局页面,jqm中提供了比较简单的网格布局。只要使用简单的CSS类就可以了。下面看一个例子代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Grid Test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/latest/jquery.mobile.min.css" /> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="http://code.jquery.com/mobile/latest/jquery.mobile.min.js"></script> </head> <body> <div data-role="page" id="first"> <div data-role="header"> <h1>Grid Test</h1> </div> <div data-role="content"> <div > <div > <p> 测试 </p> </div> <div > <p> 巩固完善基本药物制度和基层运行新机制是“十二五”期间深化医药卫生体制改革的重点,是实现2020年人人享有基本医疗卫生服务目标的重要基础。医改实施三年多来,基层医疗卫生机构综合改革全面推进,初步建立了基本药物制度,构建了维护公益性、调动积极性、保障可持续的基层运行新机制。为进一步深化改革,扩大医改成果,现就巩固完善基本药物制度和基层运行新机制提出如下意见。 </p> </div> </div> </div> </div> </body> </html>
代码中被<div >包围的将会分成两列,但是必须配合<div >才会起作用。这里ui-grid-a代表分为两列、ui-grid-b代表分为三列,以此类推。ui-block-a、ui-block-b、ui-block-c等分别代表第一列、第二列、第三列,以此类推。
代码效果如下:
现将native函数贴出来。
#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <android/log.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/statfs.h>
#include <sys/types.h>
#include <com_coder80_scaner_MainActivity.h>
//#include <fcntl.h>
#define LOG_TAG "SCANER"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define ARRAY_LENGTH 1024
static int i = 0;
static JavaVM *gvm;
static jobject giface;
static const char *classPathName = "com/coder80/scaner/MainActivity";
static JNINativeMethod methods[] = {
{ "scanDir", "(Ljava/lang/String;)V", (void *)Java_com_coder80_scaner_MainActivity_scanDir},
{ "getPathArray", "(Ljava/lang/String;)[Ljava/lang/String;", (void *)Java_com_coder80_scaner_MainActivity_getPathArray},
{ "getTracksArray", "(Ljava/lang/String;)[Lcom/coder80/scaner/Track_Info;", (void *)Java_com_coder80_scaner_MainActivity_getTracksArray}
};
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
jclass clazz = NULL;
JNIEnv* env = NULL;
jmethodID constr = NULL;
jobject obj = NULL;
LOGE("JNI_OnLoad");
gvm = vm;
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("GetEnv FAILED");
return -1;
}
clazz = (*env)->FindClass(env,classPathName);
if (!clazz) {
LOGE("Registration unable to find class '%s'", classPathName);
return -1;
}
constr = (*env)->GetMethodID(env, clazz, "<init>", "()V");
if (!constr) {
LOGE("Failed to get constructor");
return -1;
}
obj = (*env)->NewObject(env, clazz, constr);
if (!obj) {
LOGE("Failed to create an interface object");
return -1;
}
giface = (*env)->NewGlobalRef(env, obj);
if ((*env)->RegisterNatives(env, clazz, methods,
sizeof(methods) / sizeof(methods[0])) < 0) {
LOGE("Registration failed for '%s'", classPathName);
return -1;
}
return JNI_VERSION_1_4;
}
jobjectArray Java_com_coder80_scaner_MainActivity_getPathArray(JNIEnv *env, jobject obj, jstring jdirPath)
{
const char *dirPath = (*env)->GetStringUTFChars(env, jdirPath, NULL);
jclass objClass = (*env)->FindClass(env, "java/lang/String");
jobjectArray textsArray = (*env)->NewObjectArray(env,(jsize)ARRAY_LENGTH,objClass,0);
i = 0;
scan_dir2(env,dirPath,textsArray);
return textsArray;
}
void scan_dir2(JNIEnv *env,const char *directory,jobjectArray array)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if((dp = opendir(directory)) == NULL)
{
perror("opendir");
return;
}
chdir(directory);
jstring jstr;
while ((entry = readdir(dp)) != NULL)
{
stat(entry->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode))
{
if ((strcmp(entry->d_name, ".") != 0) &&
(strcmp(entry->d_name, "..") != 0) &&
(entry->d_name[0] != '.'))
{
scan_dir2(env,entry->d_name,array);
}
}
else
{
int size = strlen(entry->d_name);
if (entry->d_name[0] != '.' //隐藏文件
&& (statbuf.st_size/1024) > 300 //大于300k,表示肯能有mp3文件(忽略 <300k的mp3)
&& strcmp( ( entry->d_name + (size - 4) ) , ".mp3") == 0)
{
char* parentPath = (char*)malloc(1024);
char* absolutePath = (char*)malloc(1024);
//首先获取工作路径
getcwd(parentPath,1024);
//LOGE("parentPath = %s \n", parentPath);
strcpy(absolutePath,parentPath);
char *p = "/";
absolutePath = strcat(absolutePath,p);
absolutePath = strcat(absolutePath,entry->d_name);
//statbuf.st_size,
// LOGE("scan_dir(),file absolutePath = %s \n", absolutePath);
jstr = (*env)->NewStringUTF(env,absolutePath);
(*env)->SetObjectArrayElement(env,array,i,jstr);//必须放入jstring
i++;
// (*env)->ReleaseStringUTFChars(env,js, s);
// LOGE("scan_dir2(),i = %d,file absolutePath = %s \n\n",i, absolutePath);
free(parentPath);
parentPath = NULL;
free(absolutePath);
absolutePath = NULL;
}
}
}
chdir("..");
closedir(dp);
}
void Java_com_coder80_scaner_MainActivity_scanDir(JNIEnv *env, jobject obj, jstring jdirPath)
{
const char *path = (*env)->GetStringUTFChars(env,jdirPath,NULL);
LOGE("begin to call scan_dir() in the JNI,and path = %s \n",path);
scan_dir(path);
}
void scan_dir(const char *directory)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if((dp = opendir(directory)) == NULL)
{
perror("opendir");
return;
}
chdir(directory);
//LOGE("pyb chdir directory = %s\n",directory);
while ((entry = readdir(dp)) != NULL) {
stat(entry->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
//printf("name = %s, size = %d\n", entry->d_name, (int)statbuf.st_size);
if ((strcmp(entry->d_name, ".") != 0)
&& (strcmp(entry->d_name, "..") != 0)
&& (entry->d_name[0] != '.')) {
scan_dir(entry->d_name);
}
} else {
int size = strlen(entry->d_name);
if (entry->d_name[0] != '.'
&& (statbuf.st_size/1024) > 300 //大于300k,表示肯能有mp3文件(忽略 <300k的mp3)
&& strcmp(entry->d_name + (size - 4), ".mp3") == 0){
//LOGE("scan_dir(),file st_size = %d \n\n",(statbuf.st_size/1024));
char* parentPath = (char*)malloc(1024);
char* absolutePath = (char*)malloc(1024);
//首先获取工作路径
getcwd(parentPath,1024);
//LOGE("parentPath = %s \n", parentPath);
strcpy(absolutePath,parentPath);
char *p = "/";
absolutePath = strcat(absolutePath,p);
absolutePath = strcat(absolutePath,entry->d_name);
//statbuf.st_size,
LOGE("scan_dir(),file absolutePath = %s \n", absolutePath);
free(parentPath);
parentPath = NULL;
free(absolutePath);
absolutePath = NULL;
}
}
}
chdir("..");
closedir(dp);
}
////displayName
//jfieldID disName;
////size
//jfieldID trackSize;
////ext
//jfieldID extName;
////filePath
//jfieldID path;
////parentPath
//jfieldID parent;
//
//jobject obj_main;
JNIEXPORT jobjectArray JNICALL Java_com_coder80_scaner_MainActivity_getTracksArray(JNIEnv *env, jobject obj, jstring jdirPath){
const char *dirPath = (*env)->GetStringUTFChars(env,jdirPath,NULL);
jclass objectClass = (*env)->FindClass(env, "com/coder80/scaner/Track_Info");
jobjectArray jobj_arr= (*env)->NewObjectArray(env,(jsize)ARRAY_LENGTH,objectClass, 0);
obj_main = obj;
LOGE("in JNI getTracksArray(),dirPath = %s \n", dirPath);
//获取Java对象
/*
* 或者 同样可以获取Java对象
* jclass objectClass = env->GetObjectClass(jobject);
* */
//displayName
// disName = (*env)->GetFieldID(env,objectClass,"displayName","Ljava/lang/String;");
//// //size
//// trackSize = (*env)->GetFieldID(env,objectClass,"size"," L");
// //ext
// extName = (*env)->GetFieldID(env,objectClass,"ext","Ljava/lang/String;");
// //filePath
// path = (*env)->GetFieldID(env,objectClass,"filePath","Ljava/lang/String;");
// //parentPath
// parent = (*env)->GetFieldID(env,objectClass,"parentPath","Ljava/lang/String;");
i = 0;
scan_dir3(env,dirPath,jobj_arr);
return jobj_arr;
}
jmethodID JavaMid = NULL;
JNIEnv * jniEnvPlaying = NULL;
/*
* para obj: Track_Info object
* */
//void scan_dir3(JNIEnv *env,jobject obj,const char *directory,jobjectArray list)
void scan_dir3(JNIEnv *env,const char *directory,jobjectArray list)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if((dp = opendir(directory)) == NULL)
{
perror("opendir");
return;
}
chdir(directory);
jstring jstr;
while ((entry = readdir(dp)) != NULL)
{
stat(entry->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode))
{
if ((strcmp(entry->d_name, ".") != 0) &&
(strcmp(entry->d_name, "..") != 0) &&
(entry->d_name[0] != '.'))
{
scan_dir3(env,entry->d_name,list);
}
}
else
{
int size = strlen(entry->d_name);
if (entry->d_name[0] != '.' //隐藏文件
&& (statbuf.st_size/1024) > 300 //大于300k,表示肯能有mp3文件(忽略 <300k的mp3)
&& strcmp((entry->d_name + (size - 4)) , ".mp3") == 0)
{
char* parentPath = (char*)malloc(1024);
char* absolutePath = (char*)malloc(1024);
//首先获取工作路径
getcwd(parentPath,1024);
//LOGE("parentPath = %s \n", parentPath);
strcpy(absolutePath,parentPath);
char *p = "/";
absolutePath = strcat(absolutePath,p);
absolutePath = strcat(absolutePath,entry->d_name);
// jstring jstrDis = (*env)->NewStringUTF(env, entry->d_name);
// (*env)->SetObjectField(env, obj, disName, jstrDis);
//
//// (*env)->SetLongField(env, obj, trackSize, statbuf.st_size/1024);
//
// jstring jstrExt = (*env)->NewStringUTF(env,"mp3");
// (*env)->SetObjectField(env, obj, extName, jstrExt);
//
// jstring jstrPath = (*env)->NewStringUTF(env,absolutePath);
// (*env)->SetObjectField(env, obj, path, jstrPath);
//
// jstring jstrParentPath = (*env)->NewStringUTF(env,absolutePath);
// (*env)->SetObjectField(env, obj, parent, jstrParentPath);
jclass classTrackInfo = (*env)->FindClass(env,"com/coder80/scaner/Track_Info");
// 获取Track_Info类的构造函数ID
jmethodID midInit = (*env)->GetMethodID(env,classTrackInfo,"<init>", "()V");
//构造Track_Info对象
jobject objTrackInfo = (*env)->NewObject(env,classTrackInfo,midInit);
/*查找java中的setDisplayName方法的ID,
* @para:obj Track_Info类的对象
* @para:setDisplayName为Java中的函数名称
* @(Ljava/lang/String;)V 表示String类型的参数。返回值V代表void
* */
JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setDisplayName","(Ljava/lang/String;)V");
if (JavaMid == NULL) {
LOGE("pyb setDisplayName() fun not found!");
return;
}
jstring jstrDis = (*env)->NewStringUTF(env,entry->d_name);
//执行setDisplayName方法 jstrDis --> displayName
(*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrDis);
JavaMid = NULL;
//************************************************
//查找java中的setSize方法的ID,J -----> long
JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setSize","(J)V");
if (JavaMid == NULL) {
LOGE("pyb setSize() fun not found!");
return;
}
// jstring jstrDis = (*env)->NewStringUTF(env,entry->d_name);
// //执行setSize方法 statbuf.st_size --> size
(*env)->CallVoidMethod(env,objTrackInfo,JavaMid,statbuf.st_size);
JavaMid = NULL;
//end
//查找java中的setExt方法的ID,
JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setExt", "(Ljava/lang/String;)V");
if (JavaMid == NULL) {
LOGE("pyb setExt() fun not found!");
return;
}
jstring jstrExt = (*env)->NewStringUTF(env,"mp3");
//执行setExt方法 jstrExt --> ext
(*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrExt);
JavaMid = NULL;
//查找java中的setFilePath方法的ID,
JavaMid = (*env)->GetMethodID(env,classTrackInfo, "setFilePath","(Ljava/lang/String;)V");
if (JavaMid == NULL) {
LOGE("setFilePath() fun not found!");
return;
}
jstring jstrPath = (*env)->NewStringUTF(env,absolutePath);
//执行setFilePath方法 jstrPath --> filePath
(*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrPath);
JavaMid = NULL;
//查找java中的setParentPath方法的ID,
JavaMid = (*env)->GetMethodID(env,classTrackInfo, "setParentPath","(Ljava/lang/String;)V");
if (JavaMid == NULL) {
LOGE("setParentPath() fun not found!");
return;
}
jstring jstrParentPath = (*env)->NewStringUTF(env,parentPath);
//执行setParentPath方法 jstrParentPath --> parentPath
(*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrParentPath);
JavaMid = NULL;
(*env)->SetObjectArrayElement(env,list,i,objTrackInfo);
// LOGE("scan_dir3(),i = %d,file absolutePath = %s \n\n",i, absolutePath);
i++;
free(parentPath);
parentPath = NULL;
free(absolutePath);
absolutePath = NULL;
}
}
}
chdir("..");
closedir(dp);
}
在C中调用Java方法,首先需要构建一个Java中类的实例。
//查找Track_Info类 jclass classTrackInfo = (*env)->FindClass(env,"com/coder80/scaner/Track_Info"); // 获取Track_Info类的构造函数ID jmethodID midInit = (*env)->GetMethodID(env,classTrackInfo,"<init>", "()V"); //构造Track_Info对象 jobject objTrackInfo = (*env)->NewObject(env,classTrackInfo,midInit);GetMethodID函数中参数值"<init>"表示Track_Info类默认的构造函数。之后开始调用setDisplayName()方法.
JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setDisplayName","(Ljava/lang/String;)V");
if (JavaMid == NULL) {
LOGE("pyb setDisplayName() fun not found!");
return;
}
jstring jstrDis = (*env)->NewStringUTF(env,entry->d_name);
//执行setDisplayName方法 jstrDis --> displayName
(*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrDis);
JavaMid = NULL; 代码段中GetMethodID(env,classTrackInfo,"setDisplayName","(Ljava/lang/String;)V");
1."setDisplayName"表示java中的
public void setDisplayName(String displayName) {
this.displayName = displayName;
} 2."(Ljava/lang/String;)V"中Ljava/lang/String;表示参数类型:String。V 表示 返回值类型
调用Java中的setSize函数。
//查找java中的setSize方法的ID,J -----> long
JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setSize","(J)V");
if (JavaMid == NULL) {
LOGE("pyb setSize() fun not found!");
return;
}
// jstring jstrDis = (*env)->NewStringUTF(env,entry->d_name);
// //执行setSize方法 statbuf.st_size --> size
(*env)->CallVoidMethod(env,objTrackInfo,JavaMid,statbuf.st_size);
JavaMid = NULL; 代码段中:(*env)->GetMethodID(env,classTrackInfo,"setSize","(J)V"); 参数值"(J)V" J表示 java中的long类型数据。 public void setSize(long size) {
// Log.e("Track_Info.java", "setSize() called in JNI, size = " + size);
this.size = size;
}jmethodID GetMethodID(JNIEnv *env, jclass clazz,const char *name, const char *sig);参数const char *sig表示方法签名,有特定的格式:(param-type)ret-type,括号内表示该方法传入参数类型,后面的是返回类型
其中param-type和ret-type都是由特定符号组成,各java primitive type都有各自对应符号如下表。
例如,在本例中,需要调用 public native Track_Info[] getTracksArray(String dirPath);在JNI_OnLoad函数中可以看到
其signature就是 (Ljava/lang/String;)[Lcom/coder80/scaner/Track_Info;
Ljava/lang/String;表示参数类型
[Lcom/coder80/scaner/Track_Info;表示函数getTracksArray的返回值为对象数组。
另外千万别忘记L fully-qualified-class ; 这个格式后面的那个;号。
主要类代码如下:
package com.coder80.scaner;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private Button mbtn;
private Button mbtnJava;
private long mTime;
private TextView mTextView;
private File mSdcardFile;
private String mFlagJava = "java";
private String mFlagC = "native";
private boolean mIsClick; //防止多次点击
private Track_Info mTrack;
private List<Track_Info> mTrackList = new ArrayList<Track_Info>();
private Track_Info[] mTracks;// = new Track_Info[100];
// char[] a = new char[100];
private boolean mIsExit;//sdcard是否存在
private void log_msg(String msg) {
if(true){
Log.e(getClass().getSimpleName(), msg);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIsClick = false;
mIsExit = true;
mTrack = new Track_Info();
mSdcardFile = Environment.getExternalStorageDirectory();
Log.e("pyb", " mSdcardFile = " + mSdcardFile.toString());
if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment
.getExternalStorageState())) {
mIsExit = true;
} else {
mIsExit = false;
Toast.makeText(MainActivity.this, "SDCard不存在,请安装!",Toast.LENGTH_LONG).show();
}
mbtn = (Button) findViewById(R.id.button1);
mbtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (mIsExit) {
if (!mIsClick){
mIsClick = true;
Log.e("pyb", " in the JNI scaner");
new MyAsyncTask().execute(mFlagC);
}
}else {
Toast.makeText(MainActivity.this, "SDCard不存在,请安装!",Toast.LENGTH_LONG).show();
}
}
});
mbtnJava = (Button) findViewById(R.id.btn2);
mbtnJava.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.e("pyb", " in the Java scaner");
new MyAsyncTask().execute(mFlagJava);
}
});
mTextView = (TextView) findViewById(R.id.TextView02);
}
public void addList(Track_Info track){
mTrackList.add(track);
}
public class MyAsyncTask extends AsyncTask<String, Long, Object> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(mTime < 1000){
mTextView.setText("花费时间: " + Long.toString(mTime) + " 毫秒");
}else{
mTime = mTime/1000;
mTextView.setText("花费时间: " + Long.toString(mTime) + " 秒");
}
mIsClick = false;
}
@Override
protected Object doInBackground(String... params) {
// TODO Auto-generated method stub
String flag = params[0];
Log.e("pyb", " doInBackground called...flag = " + flag);
long time1 = System.currentTimeMillis();
// scanDir(mSdcardFile.toString() + "/音乐");
if(flag.equals("java")){
getFiles(mSdcardFile);
for(int i = 0;i< mTrackList.size();i++){
Log.e("pyb", "mTrackList[" +i+"] path = " + mTrackList.get(i).getFilePath());
}
}else if(flag.equals("native")){
// scanDir(mSdcardFile.toString());
// array = getPathArray(mSdcardFile.toString());
mTracks = getTracksArray(mSdcardFile.toString());
Log.e("pyb", "mTracks.length = "+ mTracks.length);
for (int i = 0; i < mTracks.length; i++) {
if (mTracks[i] != null) {
Log.e("pyb", "mTracks[" +i+"] path = " + mTracks[i].getFilePath());
} else {
Log.e("pyb", "mTracks == null");
break;
}
}
}
long time2 = System.currentTimeMillis();
mTime = time2 - time1;
Log.e("pyb", "in the doInBackground(),scaner mp3 cost time = " + (time2 - time1) );
return null;
}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
static {
Log.e("pyb", " System.loadLibrary() called...");
System.loadLibrary("scan");
}
/**
* 获取音乐文件列表
* @param filePath
*/
public void getFiles(File filePath) {
File[] files = filePath.listFiles();
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory() && !files[i].isHidden() && files[i].canRead()) {
getFiles(files[i]);
} else {
// Mp3support
String displayName = files[i].getName();
if (displayName.endsWith(".mp3") || displayName.endsWith(".MP3")) {
// String[] strarray = displayName.split("\\.");
// String path = files[i].getParentFile().toString();
String fileName = files[i].getName();
String[] strarray=fileName.split("\\.");
// String displayName = strarray[0];
String ext = strarray[1];
String filepath = files[i].toString();
String parentPath = files[i].getParentFile().toString() + "/";
mTrack = new Track_Info();
mTrack.setDisplayName(displayName);
mTrack.setExt(ext);
mTrack.setFilePath(filepath);
mTrack.setParentPath(parentPath);
mTrackList.add(mTrack);
}
}
}
}
}
public native void scanDir(String dirPath);
public native String[] getPathArray(String dirPath);
public native Track_Info[] getTracksArray(String dirPath);
}
通过本例,可以了解JNI使用方法,对稍微复杂的JNI编程,例如从native层调用Java层对象的讲解,是有一定的帮助的。
demo代码已经上传到博客资源中!