如何快速找回意外删除的Excel文件?
992
2022-05-30
我们知道,Android系统的各个模块提供了非常强大的功能(比如电话,电源和设置等),通过使用这些功能,应用程序可以表现的更强大,更灵活。不过,使用这些功能并不是无条件的,而是需要拥有一些权限。接下来,我们就开始讲解另一个非常重要的知识点——应用程序权限声明,其中主要包括应用程序的权限声明,自定义应用程序的访问权限和SDK版本限定。
1.
应用程序在不同的场景下可能需要上表所示的某些权限,比如当我们需要使用SD卡时,则需要申请SD卡相关权限。下面我们举例来解释这个问题。
在这个实例中,我们将改造HelloWorld应用程序,并在sdcard的根目录下添加一个名为“abc.txt”的文本文件。由于需要访问外部存储设器,因此需要申请android.permission.WRITE_EXTERNAL_STORAGE权限,否则代码将会失败。具体步骤如下所示。
①需要在HelloWorld应用程序的AndroidManifest.xml文件中添加相应的权限,如下列代码所示:
②要在原来的代码中添加一些创建文件的代码,如下所示:
public class MainActivity extends FragmentActivity { private static final String SDCARD= Environment.getExternalStorageDirectory()+File.separator; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(savedInstanceState==null){ getSupportFragmentManager().beginTransaction().add(android.R.id.content,new FileFragment()).commit(); } } public static class FileFragment extends Fragment { public FileFragment(){} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.file_fragment,container,false); Button mybut= (Button) view.findViewById(R.id.mybut); mybut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { File sdcardFile=new File(SDCARD+"abc.txt"); try { sdcardFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } }); return view; } } }
③启动程序,这时在sdcard所链接的目录下,我们会发现已经建立了abc.txt文件,如下图所示。
最后我们来做一个实验,将AndroidManifest.xml文件中的
从日志中我们可以发现程序抛出了java.io.IOException异常,并且提示“Permission denied”,而它发生的地方,正好是创建文件的地方。因此,我们可以得出一个结论,在试图读写外部存储设备的时候,必须先要申请android.permission.WRITE_EXTERNAL_STORAGE这个权限,否则程序抛出警告性异常,相关操作也就无法进行。
Android提供了丰富的软硬件功能模块,它能让应用程序变得强大,开发过程也更便捷,但在使用前,必须要为应用程序申请必要的权限。这点非常重要,否则应用程序就会出现莫名其妙的错误。
正如前面的实例中看到的结果,如果没有相应的权限,就无法创建文件,而程序并没有显示一个异常的提示,这时我们就可能要花费大量的时间去找问题的根源。
因此,本人建议大家开发之前仔细分析需求,分析应用为什么功能,而这些动能是否需要权限才可以访问。
2.
前面我们学习了如何使用权限。其实,应用程序除了可以使用权限之外,还可以定义自己的权限,用来限制对本应用程序或其他应用程序的特殊组件或功能访问。在这里,我们来学习
手动向AndroidManifest.xml文件中添加一个
android:icon="drawable resource" android:logo="drawable resource" android:label="string resource" android:name="string" android:permissionGroup="string" android:protectionLevel=["normal"|"dangerous"|"signature"|"signatureOrSystem"]/> 以上代码中,需要说明的有以下3个属性。 ①android:name:声明权限的名称。这个名称必须是唯一的,因此,应该使用Java风格的命名,比如com.test.permission.TEST。 ②android:permissionGroup:声明权限从属于哪一个权限组,这个权限组可以是Android预编译的,也可以是自定义的。下表列除了Android系统预编译的系统权限组。 ③android:protectionLevel:描述了隐含在权限中的潜在风险,该属性的值可以是下表中的一个字符串。 在 在Android系统提供的应用程序中,有一些定义了自己的权限,比如Launcher。下面的代码片段用Launcher 的AndroidManifest.xml片段来说明如何手动声明自己的权限: android:name="com.android.launcher.permission.INSTALL_SHORT-CUT" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" android:protectionLevel="normal" android:label="@string/permlab_install_shortcut" android:description="@string/perdesc_install_shortcut"/> 因为声明权限这一功能使用频率比较低,因此读者在开发应用程序的时候需要思考是否有必要声明自己的权限。 3. 大家都知道,软件对于平台版本是的一定要求的。如果平台版本能够达到软件运行的要求,那就能保证软件的稳定性。比如,大家都知道NFC功能是不能在Android 1.5中运行的,如果正在开发带类似功能的应用程序,那就必须对所在平台有所要求,而 使用此节点的代码如下所示: android:targetSdkVersion="integer" android:maxSdkVersion="integer"/> ①android:minSdkVersion:用于指定要运行应用程序所需的最小API级别。如果系统的API级别比该属性指定的值要小,则Android系统会阻止用户安装此应用。在大多数情况下,应指定这个属性。如果没有指定该属性,那么系统会认为此属性值为“1”。 ②android:targetSdkVersion:用于指定应用程序的目标API级别。 ③android:maxSdkVersion:指定最大的API级别。 4. android:handleProfiling=["true"|"false"] android:icon="drawable resource" android:label="string resource" android:name="string" android:targetPackage="string"> 下面详细说明这些属性: ①android:functionalTest:标识这个Instrumentation类是否作为一个功能测试运行,它的默认值是false。 ②android:handleProfiling:标识这个Instrumentation对象是否打开和关闭性能分析,它的默认值是false。 ③android:icon:这个属性代表这个Instrumentation类的图标 ④android:label:该属性是Instrumentation类的标题。 ⑤android:name:该属性是Instrumentation子类的名称,是一个类的Java风格的名称,例如com.example.liyuanjinglyj.myInstrumentation。 ⑥android:targetPackage:该属性是需要监控的目标应用程序名称,这个名称来自与目标应用程序AndroidManifest.xml中 当然在eclipse需要专门创建一个测试项目,而且还要配置这个节点,但是在android studio并不需要这么做,考虑到2015年底谷歌不再支持eclipse,所以只讲解android studio单元测试,而讲解这个节点是因为到现在eclipse依然有大量的开发者使用,所以,讲解了节点的详细说明。 下面举例说明如何进行单元测试: ①创建项目,依然拿我们一直使用的HelloWorld做实验,你会发现项目目录里面有这样一个测试包: ②右键点击这个包,选择NEW-CLASS菜单项,新建MyFirstTest继承自ActivityInstrumentationTestCase2 package com.example.liyuanjing.helloworld; import android.test.ActivityInstrumentationTestCase2; /** * Created by liyuanjing on 2015/7/14. */ public class MyFirstTest extends ActivityInstrumentationTestCase2 在这段代码中,ActivityInstrumentationTestCase2 ③我们测试内容为,在编辑框中输入一些字符,当点击按钮后,文本框等于编辑框输入的字符串,MainActivity代码如下: public class MainActivity extends FragmentActivity { private static final String SDCARD= Environment.getExternalStorageDirectory()+File.separator; private FileFragment fileFragment=new FileFragment(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(savedInstanceState==null){ getSupportFragmentManager().beginTransaction().add(android.R.id.content,fileFragment).commit(); } } public static class FileFragment extends Fragment { private View mRootView; public FileFragment(){} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.file_fragment,container,false); final EditText myEdit=(EditText)view.findViewById(R.id.myEdit); final TextView content=(TextView)view.findViewById(R.id.content); Button myBut=(Button)view.findViewById(R.id.myBut); myBut.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { content.setText(myEdit.getText().toString()); } }); this.mRootView=view; return view; } public View getRootView(){ return this.mRootView; } } public FileFragment getFragment(){ return fileFragment; } } 测试类的代码如下: public class MyFirstTest extends ActivityInstrumentationTestCase2 注意: Ⅰ在MyFirstTest类的构造放中,由于指定了被测试项目的Activity的详细信息,就使得MyFirstTest与Activity关联上。 ⅡsetUp()方法是一个重写的方法,它的作用是在测试前做必要的设置,比如实例化一些对象,打开网络等,它与tearDown()方法成对出现。这里我们没有实现tearDown()方法,当测试完成以后,框架会自动回调基类,也就是tearDown()方法。 最后,运行测试类,如下图所示: 当系统完成测试后,就可以在Android studio集成开发环境中得到下图所示的结果: 在图中可以看到,编写的Test测试类返回值为OK,这就证明测试达到了预期的目的。 Android 网络
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。