安卓 Android之开发简单小应用(三)
16lz
2021-01-26
安卓 Android之开发简单小应用(三)
一、简述
一个简单的txt文本编辑器。
工程打包:链接: https://pan.baidu.com/s/1jO7tqv_HI-ubfuNV3IxVVA 提取码: 47zr
蓝奏:https://www.lanzous.com/i2fy0yf
二、效果
三、工程结构
四、源文件
TxtReader.java文件
package com.liang.notes;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.util.Timer;import java.util.TimerTask;import com.liang.notes.R;import android.annotation.SuppressLint;import android.app.Activity;import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.os.Bundle;import android.os.Environment;import android.text.InputFilter;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.view.inputmethod.InputMethodManager;import android.widget.Button;import android.widget.EditText;import android.widget.GridLayout;import android.widget.TextView;import android.widget.Toast;public class TxtReader extends Activity implements OnClickListener { /** Called when the activity is first created. */private String filePath = "";//保存文件的绝对路径private String fileName = "";//文件名 @SuppressLint("NewApi") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);//设置为没有标题栏,自定义一个标签作为标题 setContentView(R.layout.main);//设置布局 //获取控件对象,并监听点击事件 Button fileOpenBtn = (Button)findViewById(R.id.btn_open); fileOpenBtn.setOnClickListener(new OpenFileAction()); Button btnexit = (Button)findViewById(R.id.btn_exit); btnexit.setOnClickListener(this); Button btnsave = (Button)findViewById(R.id.btn_save); btnsave.setOnClickListener(this); Button btnsaveas = (Button)findViewById(R.id.btn_saveas); btnsaveas.setOnClickListener(this); Button btnfind = (Button)findViewById(R.id.btn_find); btnfind.setOnClickListener(this); Button btnnew = (Button)findViewById(R.id.btn_new); btnnew.setOnClickListener(this); //如果是文件关联方式打开文件 try { Intent intent = getIntent(); if(intent.getType().equals("text/plain")) { readFile( intent.getData().getPath() ); } }catch(Exception e){} } @Override //子页面返回时执行protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode == 1 && resultCode == 1){//有多个页面时根据请求码和结果码判断是哪一个子页面结束返回,并相应的做出响应 Bundle bunde=data.getExtras();//获取数据束 readFile( bunde.getString("path") );//类似于键值对,根据键"path"获取对应的值(子页面传回来的数据) }} private void readFile(String path)//根据文件爱你绝对路径打开文件 { if(!path.equals("") && !path.trim().equals(""))//文件名不为空 { filePath = path; fileName = filePath.substring(filePath.lastIndexOf("/")+1,filePath.length());//根据绝对路径得到文件名,(用来设置标题)TextView tvtitle = (TextView)findViewById(R.id.tv_title);//获取便签对象,作为标题try{tvtitle.setText(fileName+"-我的记事本");//设置文本EditText tv = (EditText) findViewById(R.id.edt_contents);//获取到多行编辑框String code = jugeCode();//简单判断文件编码String fileContent = getStringFromFile(code);//获取到文件内容tv.setText(fileContent);//将编辑框的内容设置为文件内容}catch(Exception e){filePath = "";fileName = "";Toast.makeText(this, "获取数据异常",Toast.LENGTH_SHORT).show();} } } public String jugeCode()//简单的判断应该用什么编码打开文件 { String code = "UTF8"; String content = getStringFromFile(code);// 用UTF-8编码读取 if( content.contains("�"))//出现"�"的情况,可能是中文 { code = "GB2312";//将编码设置为 GB2312 content = getStringFromFile(code);// 再次读取 if( content.contains("�"))//出现"�"的情况,可能是Unicode { code = "Unicode";//将编码设置为 Unicode } } return code; }public String getStringFromFile(String code)//按照一定的编码格式读取txt文件{try {StringBuffer sBuffer = new StringBuffer();//用来存放文件内容FileInputStream fInputStream = new FileInputStream(filePath);//根据绝对路径创建数据流InputStreamReader inputStreamReader = new InputStreamReader(fInputStream, code);//按照code创建输入流BufferedReader in = new BufferedReader(inputStreamReader);if(!new File(filePath).exists())//如果文件不存在{in.close();//关闭流return null;//直接返回}while (in.ready()) {sBuffer.append(in.readLine() + "\n");//一行一行的读取,并追加到sBuffer中}in.close();//关闭流return sBuffer.toString();//返回文件内容} catch (Exception e) {e.printStackTrace();}return null;}class OpenFileAction implements OnClickListener {public void onClick(View v) {//这是另外一种方式实现监听//"打开"按钮的监听事件处理,跳转到文件列表界面Intent in = new Intent(TxtReader.this, ListAllFileActivity.class);startActivityForResult(in, 1);//设置请求码为1} }@SuppressLint("NewApi") @Overridepublic void onClick(View arg) {//监听事件处理switch (arg.getId()) {case R.id.btn_new://新建按钮EditText tv = (EditText) findViewById(R.id.edt_contents);//获取到文本编辑框对象tv.setText("");//清空内容filePath = "";//清空路径fileName = "";//清空文件名TextView tvtitle = (TextView)findViewById(R.id.tv_title);//获取到标题标签tvtitle.setText("未命名.txt-我的记事本");//设置文本break; case R.id.btn_save://保存按钮 if(fileName.isEmpty())//文件名为空,说明是新建文件(未命名) { //弹出对话框,让用户输入文件名 AlertDialog.Builder builderSave = new AlertDialog.Builder(this); builderSave.setTitle("保存"); //对话框标题 builderSave.setMessage("请输入文件名!");//对话框提示信息 final EditText edtname = new EditText(this);//创建一个输入框对象 //设置文件名输入框属性 edtname.setSingleLine();//设置为单行输入 edtname.setText("未命名.txt");//设置文本 edtname.setSelection(0, 3);//选中文本的第0开始的3个字符(就是选中"未命名"3个字符) edtname.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(64)//设置输入最大长度 }); builderSave.setView(edtname);//将输入框添加到对话框 builderSave.setNegativeButton("取消",null); //添加取消按钮 //添加确定按钮,并且添加单击事件处理 builderSave.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String name = edtname.getText().toString().trim();//获取输入框的文本内容,并去掉前后空格 if(!(name.isEmpty()))//如果输入的文件名不为空 { if(!name.endsWith(".txt"))//文件名没有以".txt"结尾 { name += ".txt";//在结尾处添加".txt" } fileName = name;//更新为当前文件名 //获取文本编辑框对象 EditText edtcontent = (EditText) findViewById(R.id.edt_contents); //将文本编辑框内容保存到文件 boolean b = Save(name,edtcontent.getText().toString(),true); if(b) { TextView tvtitle = (TextView)findViewById(R.id.tv_title);//获取到标题标签 tvtitle.setText(fileName+"-我的记事本");//设置文本 //弹出小黑框提示 Toast.makeText(TxtReader.this,"已保存",Toast.LENGTH_SHORT).show(); } } else//文件名为空 { //提示 Toast.makeText(TxtReader.this,"文件名不能为空",Toast.LENGTH_SHORT).show(); } } }); builderSave.show();//弹出保存对话框 //等待对话框弹出之后,再弹出软键盘 new Timer().schedule(new TimerTask() { @Override public void run() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(edtname, 0); } },300); } else //文件名不为空,说明是打开的文件,或者是已经保存过一次的文件 { if(!fileName.endsWith(".txt"))//文件名不以".txt"结尾 { fileName += ".txt";//在结尾加上".txt" } //获取文本输入框对象 EditText edtcontent = (EditText) findViewById(R.id.edt_contents); //获取文本输入框的内容 String txt = edtcontent.getText().toString(); //System.out.println(txt); //覆盖保存到文件中, boolean b = Save(fileName,txt,false); //提示保存成功 if(b)Toast.makeText(TxtReader.this,"已保存",Toast.LENGTH_SHORT).show(); } break; case R.id.btn_saveas://另存为按钮 if(true) { //弹出文件两寸为对话框 AlertDialog.Builder builderSaveas = new AlertDialog.Builder(this); builderSaveas.setTitle("另存为");//设置标题 builderSaveas.setMessage("请输入文件名!");//设置提示信息 final EditText edtname = new EditText(this);//创建一个输入框对象 //设置文件名输入框属性 edtname.setSingleLine();//设置为单行输入 edtname.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(64)//设置输入最大长度 }); if(filePath.isEmpty())//如果原来文件名为空,说明是新建文件 { edtname.setText("未命名.txt");//设置文本 edtname.setSelection(0, 3);//选中文本的第0开始的3个字符(就是选中"未命名"3个字符) } else //如果原来文件名不为空,说明是不是新建文件 { //确保文件名是以".txt"结尾的 if(!fileName.endsWith(".txt")) { fileName += ".txt"; } edtname.setText(fileName);//将文本框初始文本为原来的文件名 int top = fileName.indexOf(".txt")+1; edtname.setSelection(0, top);//选中原来的文件名 } builderSaveas.setView(edtname);//将编辑框添加到另存为对话框 builderSaveas.setNegativeButton("取消",null); //添加取消按钮 //添加确定按钮,并监听点击事件 builderSaveas.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String name = edtname.getText().toString().trim();//获取输入框的内容并去掉两端的空格 if(!(name.isEmpty()))//如果文件名不为空 { //确保文件名以".txt"结尾 if(!name.endsWith(".txt")) { name += ".txt"; } fileName = name;//设置当前文件名 //获取文本输入框对象 EditText edtcontent = (EditText) findViewById(R.id.edt_contents); //将文件内容覆盖保存 boolean b = Save(name,edtcontent.getText().toString(),false); //提示保存成功 if(b) Toast.makeText(TxtReader.this,"已保存",Toast.LENGTH_SHORT).show(); } else//文件名为空 { Toast.makeText(TxtReader.this,"文件名不能为空",Toast.LENGTH_SHORT).show(); } } }); builderSaveas.show();//弹出另存为对话框 //等待对话框弹出之后,再弹出软键盘 new Timer().schedule(new TimerTask() { @Override public void run() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(edtname, 0); } },300); } break; case R.id.btn_find://查找按钮 //查找、替换对话框 AlertDialog.Builder builder = new AlertDialog.Builder(TxtReader.this); builder.setTitle("查找/替换"); //设置标题 //创建一个网格布局 GridLayout grid = new GridLayout(TxtReader.this); grid.setColumnCount(2);//设置列数 //创建替换为标签 TextView viewrpl = new TextView(TxtReader.this); viewrpl.setText("替换为:");//设置文本 //创建替换文本输入框 final EditText edtrpl = new EditText(TxtReader.this); edtrpl.setSingleLine();//设置为单行 edtrpl.setHeight(45);//设置高度 edtrpl.setPadding(3, 0, 3, 0);//设置内边距,左上右下 edtrpl.setHint("请输入替换为的字符");//设置初始文本(获取焦点是次文本消失) edtrpl.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(64)//设置最大长度 }); grid.addView(viewrpl, 0);//将替换为标签添加到网格布局的第0列 grid.addView(edtrpl, 1);//将替换为输入框添加到网格布局的第1列 //创建查找标签 TextView viewfind = new TextView(TxtReader.this); viewfind.setText("查找:");//设置文本 //创建查找输入框 final EditText edtfind = new EditText(TxtReader.this); edtfind.setSingleLine();//设置为单行 edtfind.setHeight(45);//设置高度 edtfind.setPadding(3, 0, 3, 0);//设置内边距 edtfind.setHint("请输入要查找的字符");//设置初始字符 edtfind.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(64)//设置最大长度 }); grid.addView(viewfind, 0);//将查找标签添加到网格布局的第0列 grid.addView(edtfind, 1);//将查找输入框添加到网格布局的第1列 builder.setView(grid);//将网格布局添加到对话框 builder.setNegativeButton("取消",null); //添加取消按钮 //添加查找按钮并监听点击事件 builder.setNeutralButton("查找", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String findStr = edtfind.getText().toString();//获取到要查找的文本 if(findStr.isEmpty())//为空,什么都不做 { } else//不为空 { //获取文本编辑框对象 EditText edtcontent = (EditText) findViewById(R.id.edt_contents); int start = -1;//选中文本的开始索引 //在全部内容中查找目标,并记下找到的开始位置 start = edtcontent.getText().toString().indexOf(findStr); if(start != -1)//已经找到 { int stop = start+findStr.length();//选中文本的结束索引 edtcontent.setSelection(start, stop);//将找到的文本选中 //提示找到 Toast.makeText(TxtReader.this,"已找到!",Toast.LENGTH_SHORT).show(); } else//未找到 { Toast.makeText(TxtReader.this,"未找到!",Toast.LENGTH_SHORT).show(); } } } }); //添加替换按钮 builder.setPositiveButton("替换", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //String rplstr = edtrpl.getText().toString();//获取到要替换为的文本 Toast.makeText(TxtReader.this,"替换成功!",Toast.LENGTH_SHORT).show(); } }); builder.show(); //弹出对话框 break; case R.id.btn_exit://退出按钮 //退出确认对话框 AlertDialog.Builder builderExit = new AlertDialog.Builder(this); builderExit.setTitle("退出"); //标题 builderExit.setMessage("您确定退出吗?");//提示信息 builderExit.setNegativeButton("取消",null);//添加取消按钮 //添加确定按钮 builderExit.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //判断文件是否有修改并且尚未保存,如果有应该提示用户。。。 finish();//关闭页面 } }); builderExit.show(); break;}}//保存到文件 filename:文件名 content:内容 isAppend:是否追加,(否则覆盖)public static boolean Save(String filename,String content,boolean isAppend) { //在文本文本中追加内容 String sdCardDir =Environment.getExternalStorageDirectory().getAbsolutePath();File file = new File(sdCardDir,filename);BufferedWriter out = null; try { if(!file.exists())//文件不存在 { file.createNewFile();//创建新文件 } FileOutputStream outStream = new FileOutputStream(file,isAppend); outStream.write(content.getBytes());//写入文件 outStream.close();//关闭流 return true; } catch (Exception e) { e.printStackTrace(); } finally { try { if(out != null){ out.close(); } } catch (IOException e) { e.printStackTrace(); } }return false; } }
ListAllFileActivity.java文件
package com.liang.notes;import java.io.File;import java.util.ArrayList;import java.util.List;import com.liang.notes.R;import android.annotation.SuppressLint;import android.app.ListActivity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.ArrayAdapter;import android.widget.ListView;/*展现全部文件的Activity*/public class ListAllFileActivity extends ListActivity {/*文件列表*/private List fileNameList;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.filelist);//设置布局//初始化文件列表File path = android.os.Environment.getExternalStorageDirectory();File[] f = path.listFiles();fill(f);}@Override //选项点击事件protected void onListItemClick(ListView l, View v, int position, long id) {//bundle = new Bundle();File file = fileNameList.get(position);if (file.isDirectory())//如果是文件夹,则进入{File[] f = file.listFiles();fill(f);}else //如果是文件{//将选中的文件的绝对路径返回给主页面Intent intent = new Intent(ListAllFileActivity.this, TxtReader.class);//bundle.putString(fileNameKey, file.getAbsolutePath());intent.putExtra("path",file.getAbsolutePath()); setResult(1, intent);//设置返回码为1 finish();}}// 读取文件列表,并设置listviewprivate void fill(File[] files) {fileNameList = new ArrayList();for (File file : files) {if (isValidFileOrDir(file)) {fileNameList.add(file);}}ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, fileToStrArr(fileNameList));setListAdapter(adapter);}/*检查是否为合法的文件名,或者是否为路径*/@SuppressLint("DefaultLocale") private boolean isValidFileOrDir(File file){if (file.isDirectory()) {return true;}else {String fileName = file.getName().toLowerCase();if (fileName.endsWith(".txt")) {return true;}}return false;}private String[] fileToStrArr(List fl){ArrayList fnList = new ArrayList();for (int i = 0; i < fl.size(); i++) {String nameString = fl.get(i).getName();fnList.add(nameString);}return fnList.toArray(new String[0]);}}
AndroidManifet.xml文件
<?xml version="1.0" encoding="utf-8"?>
main.xml
<?xml version="1.0" encoding="utf-8"?>
五、总结
1、添加对储存卡的读写权限
2、弹出文件名输入框同时弹出软键盘(输入法)
需要等待对话框创建完毕。
//等待对话框弹出之后,再弹出软键盘new Timer().schedule(new TimerTask() {@Override public void run() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);imm.showSoftInput(edtname, 0);} },300);
3、应用图标设置
4、将应用关联txt文件类型
也就是点击txt文件,让自己的app出现在txt格式文件的默认打开列表中。
在AnsroidManifest.xml中添加
Intent intent = getIntent();String fileType = intent.getType();//文件类型String filePath = intent.getData().getPath();//文件结对路径
5、待完善
1) 替换功能尚未完成。
2) 细节有待完善,比如退出前判断文件是否已经保存了。
3) 打开文件部分没有路径返回。
4) 文件编码只是简单的处理UTF-8,ANSI,Unicode编码。
更多相关文章
- Android(SpreadTurm)开锁前设置一个亮度,解锁后再设置一个亮度
- Android材料设计库之折叠式布局你应该知道的一切
- SharedPreferences存储
- Android之官方导航栏之Toolbar(Toolbar+DrawerLayout+ViewPager+
- android 通过platform.pk8,platform.x509.pem生成jks签名文件
- Android恢复出厂设置
- android中的权限说明
- Android小程序——拨打电话
- Android手机归属地查询工具