拓展知识:

             MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面 显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于 映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。

                模型-视图-控制器(MVC)是Xerox PARC在二十世纪八十年代为编程语言Smalltalk-80发明的一种软件设计模式,已被广泛使用。后来被推荐为Oracle旗下Sun公司Java EE平台的设计模式,并且受到越来越多的使用ColdFusion和PHP的开发者的欢迎。模型-视图-控制器模式是一个有用的工具箱,它有很多好处,但也有一些缺点。MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式:[1] Model(模型)表示应用程序核心(比如数据库记录列表)。 View(视图)显示数据(数据库记录)。 Controller(控制器)处理输入(写入数据库记录)。

模式同时提供了对 HTML、CSS 和 JavaScript 的完全控制。

      Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。 

           通常模型对象负责在数据库中存取数据。

      View(视图)是应用程序中处理数据显示的部分。  

           通常视图是依据模型数据创建的。

       Controller(控制器)是应用程序中处理用户交互的部分。 

        通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

     MVC 分层有助于管理复杂的应用程序,因为您可以在一个时间内专门关注一个方面。例如,您可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。MVC 分层同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。安卓中,也遵循MVC的设计模式。M-业务层,V-布局,对应XML布局,C-Activity。

       1:从视图中获取数据 2:调用模型层处理,在进行安卓文件存储代码实现时,需要涉及到io流的设计模式,测试业务层代码,进行单元测试,目的是,在确定业务方法没有问题的情况下,编写控制层。

      主要实现过程:1:模型层的代码实现:


package com.example.fileoperatedemo.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import com.example.fileoperatedemo.MainActivity;

import android.content.Context;
import android.os.Environment;
import android.view.View.OnClickListener;

public class FileService
{
	private Context context;
	private String fileName;

	public FileService(Context context2, String fileName)
	{
		this.context = (Context) context2;
		this.fileName = fileName;
	}

	public boolean save(String content)
	{
		BufferedWriter bw = null;
		boolean isSaveSucceed = false;
		try
		{
			/*
			 * 此处需要用到io留设计模式。装饰类。*
			 * 1:构建文件输出流通道:FileOutputStream,其中需要用到context的openFileOutput方法
			 * 2:用OutputStream包装FileOutputStream,装换成字符输出流,使用户输入中文时,不出现乱码。
			 * 3:使用BufferedWriter实现缓冲功能,包装Writer。
			 **/
			FileOutputStream fos = context.openFileOutput(fileName, context.MODE_PRIVATE);
			OutputStreamWriter writer = new OutputStreamWriter(fos);
			bw = new BufferedWriter(writer);//
			bw.write(content);
			isSaveSucceed = true;

		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		} finally
		{//流占用资源,最后必须进行关闭。
			if (bw != null)
				try
				{
					bw.close();
				} catch (IOException e)
				{
					e.printStackTrace();
				}
		}
		return isSaveSucceed;
	}

	public String read()
	{
		String line;
		StringBuilder sb = new StringBuilder();
		BufferedReader br = null;
		try
		{
			FileInputStream fis = context.openFileInput(fileName);
			br = new BufferedReader(new InputStreamReader(fis));
			while ((line = br.readLine()) != null)
			{
				sb.append(line);
			}

		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		} finally
		{
			if (br != null)
			{
				try
				{
					br.close();
				} catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return sb.toString();
	}

	}

2:添加需要进行单元测试的测试类,并让其继承AndroidTestCase:


com.example.fileoperatedemo.test;

import com.example.fileoperatedemo.service.FileService;

import android.test.AndroidTestCase;

public class FileServieTest extends AndroidTestCase {
    public void testSave(){
    	/*
    	 * 普通类中没有context方法。****/
    	FileService fileService=new FileService(getContext(), "test.txt");
    	fileService.save("hello world");
    }
}
3:在此处需要用到单元测试,是为了后面在确定业务层方法没有问题的情况下,然后就可以进行对控制层的编写。为了进行单元测试,必须在ManiFest.xml下:
在</activity>后天要添加:<uses-library android:name="android.test.runner"/>
在</application>后添加:      
<instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.example.fileoperatedemo" >
    </instrumentation>



2:添加需要进行单元测试的测试类,并让其继承AndroidTestCase:


1 package com.example.fileoperatedemo.test;
 2 
 3 import com.example.fileoperatedemo.service.FileService;
 4 
 5 import android.test.AndroidTestCase;
 6 
 7 public class FileServieTest extends AndroidTestCase {
 8     public void testSave(){
 9         /*
10          * 普通类中没有context方法。****/
11         FileService fileService=new FileService(getContext(), "test.txt");
12         fileService.save("hello world");
13     }
14 }


如果单元测试成功,将会显示如下绿色的进程条。不成功将会显示红色的条。:

Androidstudio 无法读取设备文件名 安卓11无法读取data文件夹_java

另外生成的text.txt在ddms-File Explorer下面的data-data-对应所在包下(在本例中就是com.example.fileoperatedemo)查看。也可以将txt导入到本地查看。

2:MainActivity:(拓展:背景音乐的添加:在res下新建一个文件夹raw,里面导入你需要的音乐。然后在调用的地方调用即可。直接在MainActivity中添加代码:


1 private MediaPlayer mMediaPlayer;
 2  
 3 private void playLocalFile() {
 4         mMediaPlayer = MediaPlayer.create(this, R.raw.in_call_alarm);
 5         //播放工程res目录下的raw目录中的音乐文件in_call_alarm
 6         try {
 7             mMediaPlayer.prepare();
 8         } catch (IllegalStateException e) {
 9             
10         } catch (IOException e) {
11            
12         }
13  
14         mMediaPlayer.start();
15         headsetplay.setEnabled(false);
16  
17         mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
18                 public void onCompletion(MediaPlayer mp) {
19                     //播完了接着播或者关闭mMediaPlayer
20             });
21     }


1 private MediaPlayer mMediaPlayer;
 2  
 3 private void playLocalFile() {
 4         mMediaPlayer = MediaPlayer.create(this, R.raw.in_call_alarm);
 5         //播放工程res目录下的raw目录中的音乐文件in_call_alarm
 6         try {
 7             mMediaPlayer.prepare();
 8         } catch (IllegalStateException e) {
 9             
10         } catch (IOException e) {
11            
12         }
13  
14         mMediaPlayer.start();
15         headsetplay.setEnabled(false);
16  
17         mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
18                 public void onCompletion(MediaPlayer mp) {
19                     //播完了接着播或者关闭mMediaPlayer
20             });
21     }


MainActivity.java如下:


package com.example.fileoperatedemo;

import android.media.MediaPlayer.OnCompletionListener;

import java.io.IOException;

import com.example.fileoperatedemo.service.FileService;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

//控制层
public class MainActivity extends Activity
{
 //此处添加了背景音乐,在程序的运行过程中播放。
     private MediaPlayer mMediaPlayer; 
       private EditText etContent;
       private Button button;
       private void playLocalFile() {        
       mMediaPlayer = MediaPlayer.create(this,R.raw.shoulder);       
            try {    
                mMediaPlayer.prepare();       
            }   catch (IllegalStateException e) {                   
            }    catch (IOException e) { 
            }
            mMediaPlayer.start();        
            
            mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {                
                public void onCompletion(MediaPlayer mp) {                          
                 }}); 
            }
        

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        playLocalFile();
        initViews();
        button=(Button) findViewById(R.id.btnOk);
        //定义弹出框
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setMessage(R.string.dialog_text).setCancelable(false).setTitle(R.string.dialog_title).setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog,int id){
                dialog.dismiss();
            }
        });
        final AlertDialog alert=builder.create();
        //绑定事件
        button.setOnClickListener(new View.OnClickListener()
        {
            
            @Override
            public void onClick(View view)
            {
                alert.show();
            }
        });
                    
    }

    private void initViews()
    {
        etContent = (EditText) findViewById(R.id.etContent);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public void save(View view)
    {
        // 从V获取数据
        String content = etContent.getText().toString();
        // 调用模型层M进行处理
        FileService fileService = new FileService(this, "data.txt");
        boolean isSavesucceed = fileService.save(content);
        if (isSavesucceed)
        {
            Toast.makeText(this, "恭喜你,保存成功了", Toast.LENGTH_LONG).show();
        }

    }
}


另外还加入了一个透明背景。在ManiFest中设置Activity Theme为Theme,Translucents使Activity透明。

运行界面如下:

Androidstudio 无法读取设备文件名 安卓11无法读取data文件夹_java_02

Androidstudio 无法读取设备文件名 安卓11无法读取data文件夹_android_03

3:代码下载请访问:

https://github.com/xuyinghuicherish/FileOperateDemo