美文网首页
3.菜单+对话框+数据存储+Content provide

3.菜单+对话框+数据存储+Content provide

作者: chaohx | 来源:发表于2017-06-20 17:00 被阅读73次

    一.菜单Menu

    1.OptionsMenu  选项菜单  也叫系统菜单,右上角的三点

        (1)高版本的菜单

                 Step1: 在menu文件夹中的XMl文件中写菜单布局

                            <item

                             android:id="@+id/action_color"

                             android:orderInCategory="100"控制再Menu中显示的顺序,数值越                                                                                       小,越靠前

                             android:showAsAction="never"控制该菜单项何时显示再ActionBar中

                                               属性:never 永远不现实再ActionBar中

                                                           always  一直显示再Action Bar中

                                                           ifRoom如果有空间,则显示再ActionBar中

                            android:title=“菜单项的文本”/>

                           //<item>元素中可嵌套<menu>元素形成二级菜单

               Step2:在Activity中调用onCreateOptionsMenu方法

                        public boolean onCreateOptionsMenu(Menu menu){

                                  //加载菜单布局 

                                  getMenuInflater().inflate(R.menu.main,menu);

                                  return true;

                        }

                Step3:重写点击菜单回调的方法

                            public boolean onOptionsItemSelected(MenuItem item){

                                  switch(item.getItemId()){

                                              .......

                                  }

                            }

    (2)低版本创建菜单,纯java代码

             在Activity中重写onCreateOptionsMenu方法

    public boolean onCreateOptionsMenu(Menu menu){

              menu.add(menu.NONE,1,menu.NONE,"低版本的菜单一");

              SubMenu subMenu = menu.addSubMenu(menu.NONE,2,menu.NONE,"sub 2");

              subMenu.add(menu.NONE,21,1,"sub 2_1");

              subMenu.add(menu.NONE,22,0,"sub 2_2");

               return true;

    }

    2.ContextMenu  上下文菜单

                                可以为任意View指定上下文菜单,长按View显示上下文菜单,

                                通常用于ListView和GridView中

    (1)在menu文件夹下的XML文件中写布局

    (2)为View注册上下文菜单

            registerForContextMenu(textView);

    (3)重写Activity中的onCreateContextMenu()方法

           /**

          *创建上下文菜单,长按View时调用该方法,每长按一次就会被调用一次

          *ContextMenu menu        需要显示的菜单

           *View view              被长按的view,且经过注册

          *ContextMenuInfo menuInfo所选择界面的额外信息(ListView,GridView,Spinner)

          *                        携带的AdapterView中的position信息

          */

         public void onCreateContextMenu(ContextMenu menu,View view,ContextMenuinfo             menuInfo){

              //加载菜单布局

              getMenuInflater().inflate(R.menu.xxx,menu);

              position = ((AdapterContextMenuInfo)menuInfo).position;

        }

    (4)重写onContextItemSelected方法,点击上下文菜单项被回调的方法

    public boolean onContextItemSelected(MenuItem item){

              switch(item.getItemId){

                                    ........

              }

    }

    3.弹出式菜单 PopupMenu  API 11 以上,可以为任意一个View创建弹出式菜单

         (1)创建弹出式菜单

              /**

               *this  上下文

               *v    当前弹出式菜单参考显示位置的UI控件

               */

               PopupMenu popupMenu = new PopupMenu(this,v);

    (2)加载菜单内容

              getMenuInflater().inflate(R.menu.xxx,popupMenu.getMenu());

    (3)为弹出式菜单添加点击事件

          popupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener(){

                   public boolean onMenuItemClick(Menuitem item){

                         switch(item.getItemId){

                                       ...........

                         }

                  }

           });

    (4)显示弹出式菜单

            popuMenu.show();

    二、对话框

    常用对话框

                            普通对话框      AlertDialog

                            进度条对话框    ProgressDialog

                            日期选择对话框  DatePickerDialog

                            时间选择对话框  TimePickerDialog

                            自定义对话框    setView()

    列表对话框(在AlertDialog的基础上设置某些属性而得)

                             普通列表对话框

                              builder.setItems(数组,new Dialoginterface.OnClickListener{})

                              单选列表对话框

                              builder.setSingleChoiceItems(数组,new                                                                                                                          Dialoginterface.OnclickListener{})

                              多选列表对话框

                              builder.setMultiChoiceItems(数组,new                                                                                                                                OnMultiChoiceClickListener{})

                              适配器列表对话框

                               builder.setAdapter(数组,new Dailoginterface.OnclickListener{})

    对话框的通用属性

                  setIcon(R.drawable.ic_launcher)  设置对话框的标题头像

                  setTitle("")                    设置标题

                  setMessage("")                  设置内容文字

                  setCancelable(ture/false)        设置点击空表出对话框是否消失

    三、Android的存储

    一.共享参数存储 (SharedPreferences)

    (1)SharedPreferences的介绍

    SharedPreferences是Android系统提供的一个通用的数据持久化框架,用于存储和读取key-value类型的原始基本数据类型对,目前支持String、int、long、float、boolean等基本类型的存储,对于自定义的对象数据类型,无法使用SharedPreferences来存储。

    SharedPreferences主要用于存储系统的配置信息。例如上次登录的用户名,上次最后设置的配置信息(如:是否打开音效、是否使用振动,小游戏的玩家积分等)。

    当再次启动程序后依然保持原有设置。SharedPreferences用键值对方式存储,方便写入和读取。

    SharedPreferences是Context上下文中的一个接口,Context提供了一个getSharedPreferences(name,mode)方法用于拿到SharedPreferences对象

    SharedPreferences里又有一个Editor接口,SharedPreferences对象中提供了一个edit()方法用于拿到Editor对象

    (2)SharedPreferences的特点

          存放轻量级数据

         本质存储形式是xml格式

         通常用于存储简单的数据信息,如记住账号,配置信息等

         应用程序卸载后,文件也会被删除

    (3)SharedPreferences存储的数据类型

        可以存放boolean,int,string,long,float,

        但不能存放对象.

    (4)getSharedpreferences(name,mode)方法的介绍

            该方法返回SharedPreferences对象,

             该方法有两个参数:

                                第一个:String name  文件名

                                第二个:int mode    一些权限  Context中提供了一些常量

                                                        Context.MODE_PRIVATE : 只有本应用可以访问

                                                        Context.MODE_WORLD_READABLE :其他应用可读

                                                       Context.MODE_WORLD_WRITEABLE : 其他应用可写

                                                       这些权限可以用+号来连接

    (5)SharedPreferences常用方法        

          sharedPreferences.edit();获取Editor对象        

          sharedPreferences.getXXX(key,默认值);                

          如:sharedPreferences.getString(key,默认值);        

          sharedPreferences.getStringSet(key,默认set); 返回set       

           sharedpreferences.getAll()  返回Map<String,?>

           sharedPreferences.contains(key) 判断是否存在某键

           editor.putXXX(key,默认值)

           editor.putStringSet(key,默认Set)

           editor.remove(key);  移除某键值对

           editor.clear();  清楚所有数据.

           editor.commit();  提交,如果不提交则写不到文件中去

    (6)SharedPreferences使用步骤

           ①通过context对象得到sharedpreferences对象

                Sharedpreferences sharedpreferences =                                                                                               context.getSharedPreferences("name",Context.MODE_PRIVATE);

           ②拿个Editor对象,并put数据

                  Editor editor = sharedpreferences.editor();

                  editor.putString(key,默认值);

                         ........

                   editor.commit();数据成功存入

    ③通过sharedpreferences对象拿值

                   sharedpreferences.getString(key,默认值);

                               ........

    二.File存储

    (1)内部存储  Internal Storage

              <1>特点: 文件只能被本应用访问,其他应用不能访问

                                当应用程勋卸载后,程序在内部存储的文件也会被删除

             <2>路径:

                               data/data/应用程序包名/files/***.**

              <3>核心方法:

                   context提供了openInputStream(name); 根据指定文件名打开输入流

                          openOutputStream(name,mode); 根据文件名打开输入流,无则创建.

                                                                                     mode同SharedPreferences一样

                          String[] fileList()    获取所有文件名称

                           File    getFileDir()  获取文件的绝对路径

                           boolean  deleteFile(name)删除某个文件 

    (2)外部存储  external storage(扩展卡 SD卡)

           <1>特点:SD卡公共目录  SD卡的私有目录

                 公共目录下的文件可以被应用程序共享,私有目录中的文件只能当前应用程序使用.当程序卸载后,公共目录中的文件不被清理,私有目录中的文件会被清理

           <2>权限:

    <!--写SD卡的权限-->

    <user-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <!--读SD卡的权限-->

    <users-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <3>SD卡的根目录

    File file = Environment.getExternalStorageDirectory();

    打印结果为:/mnt/sdcard

    <4>SD卡公共目录

    Environment.getExternalStoragePublicDirectory(String type)

                       参数type:

                             DIRECTORY_ALARMS //警报的铃声

                             DIRECTORY_DCIM //相机拍摄的图片和视频保存的位置

                             DIRECTORY_DOWNLOADS //下载文件保存的位置

                             DIRECTORY_MOVIES //电影保存的位置, 比如 通过google play下载                          的电影

                             DIRECTORY_MUSIC //音乐保存的位置

                             DIRECTORY_NOTIFICATIONS //通知音保存的位置

                             DIRECTORY_PICTURES //下载的图片保存的位置

                             DIRECTORY_PODCASTS //用于保存podcast(博客)的音频文件

                             DIRECTORY_RINGTONES //保存铃声的位置

            打印结果为:/mnt/sdcard/alarms

    <5>SD卡的私有目录

        context.context.getExternalFilesDir(null)  SD卡的私有目录的根目录

        打印结果为:/mnt/sdcard/Android/data/包名/files

        context.getExternalFilesDir(String type)  SD卡的私有目录中的指定目录

        context.getExternalCacheDir()    SD卡的私有目录的缓存目录

         打印结果为:/mnt/sdcard/Android/data/包名/cache

    <6>获取SD卡的状态

             Environment.getExternalStorageState()

    <7>读写SD卡的步骤

    ①判断SD卡的状态

            Environment.getExternalStorageState()

    ②获取sdcard的路径

             Environment.getExternalStorageDirectory()

    ③添加读写SD卡的权限

    ④执行IO操作

    <8>利用StatFs获取磁盘空间信息

              StatFs 一个模拟linux的df命令的一个类,获得SD卡和手机内存的使用情况

              StatFs的常用方法: 以block为单位.

                         getAvailableBlocks()    返回int,可用数据块个数

                         getFreeBlocks()          返回int,可用数据块个数,与上一个方法一样

                         getBlockCount()          返回int,总数据块数

                         getBlockSize()          返回int,大小,以字节为单位,每个数据块的大小

                         restate(String path)    执行一个由该对引用的文件系统

               SDK>=18时

                          statFs.getFreeBytes()    直接返回磁盘的剩余空间

                SDK<18时

                           statFs.getFreeBlocks()*statFs.getBlockSize() 计算剩余空间

    三.SQLite数据库存储

        (1)特点

                轻量级  绿色  零配置  跨平台 嵌入式

                在程序的内部,可以在任何位置通过数据库的名称访问数据库,不可跨应用访问

                路径:data/data/应用程序包名/database/**.db

    (2)SQLite知识,同java笔记

    (3)Android操作SQlite数据库的核心类

          <1>SQLiteDatabase的使用

                 SQLiteDatabase用于管理和操作数据库

                 context对象中提供了一个返回SQLiteDatabase对象的方法

                 context.openOrCreateDatabase(name,mode,CursorFactory);

                    参数:

                            name  :  数据库名称

                            mode  :  模式: SQliteDatabase.OPEN_READWRITER  读写模式

                                                     SQLiteDatabase.OPEN_READONLY    只读模式

                                                     SQLiteDatabase.CREATE_IF_NECESSARY 如果数据                                                  库不存在,则创建

                             CursorFactory:  通常为空

    SQLiteDatabase中执行SQL语句的方法: (常用)

                   void execSQL(String sql)  执行SQL语句

                  void execSQl(String sql,Object[] bindArgs) 执行SQL语句(可以有占位符)

                  Cursor rawQuery(String sql,String[]  selectionArgs) 执行查询语句(可以有占位符)

    SQLiteDatabase封装好的操作数据库的方法 (不常用)

                   insert()  插入数据到指定的表中

                    update()  更改表中指定的数据

                   delete()  删除表中指定的数据

                   query()   查询表中指定的内容

    <2>SQLiteOperHelper  维护了一个数据库及维护了一个SQLiteDatabase对象

                                             用于数据的创建.更新.和打开数据库连接

       用法:

                ①定义一个类,继承SQLiteOpenHelper

                    并重写父类的两个方法,这两个方式是系统调用的不用手动调用

                    onCreate(SQLiterDatabase  db)  第一次创建数据库时调用, 只会被调用一次

                    onUpgrade(SQLiterDatabase  db,int oldVersion, int newVersion)  数据库的版本号发生变化后,执行此方法(可能会被执行多次)

    ②必须提供一个构造方法

    public MySQLiteOpenHelper(Context context) {

                  super(context, name, CursorFactory, version);

    }

    参数:

              context:    上下文对象

              name:      数据库名字

              CursorFactory:通常为null,就是用系统的CursorFactory

              version:    版本号

    SqLiteOpenHelper对象中的方法

                   mySQLiteOpenHelper.getReadableDatabase();只读方式打开数据库连接

                   mySQLiteOpenHelper.getWritableDatabase();以读写方式打开数据库连接

    <3>Cursor

               作用类似于JDBC中resultSet, 把查询的结果封装到Cursor对象中.

                cursor就像是一个结果级上的游标, 可以向上或向下移动

                 默认游标位置在数据的上方

    cursor对象的常用方法:

    coursor.getCount()  得到游标中的数据数量

              coursor.moveToNext() 游标移动到下一条数据, 并且判断下一条数据是否存在

               coursor.moveToPrevious() 游标移动到上一条数据, 并且判断上一条数据是否存在

              coursor.moveToFirst() 游标移动到第一条数据, 并且判断第一条数据是否存在

              coursor.moveToLast()  游标移动到最后一条数据, 并且判断最后一条数据是否存在

             coursor.moveToPosition(int position) 游标移动到某一条数据, 并且判断某一条数据是否存在

             coursor.move(int offset)  游标向上或者向下移动指定的行数, 正数代表向上,负数代表向下, 并且判断数据是否存在

             cursor.getColumnIndex(columnName)  根据列名拿个下标2016/7/6

             cursor.getColumnName(columnIndex)  根据下标拿个列名

             cursor.getColumnNames()  得到所有列名组成的数组

             cursor.getPosition()      得到行标

    四.Content Provider  内容提供者(Android四大组件之一)

    (1)Content Provider的介绍,作用以及特点

             为了达到不同应用程序之间的数据共享,Android提供了ContentProvider.

             例如我们需要操作系统里的媒体库、通讯录等,这时我们就可能通过                           ContentProvider来满足我们的需求了

    <1>ContentProvider为存储和获取数据提供了统一的接口。ContentProvide对数据进行封装,不用关心数据存储的细节。使用表的形式来组织数据。

    <2>使用ContentProvider可以在不同的应用程序之间共享数据。

    <3>Android为常见的一些数据提供了默认的ContentProvider(包括音频、视频、图片和通讯录等)。

    总的来说使用ContentProvider对外共享数据的好处是统一了数据的访问方式。

    (2)ContentProvider类的介绍

                 ContentProvider是一个抽象类,要想创建ContentProvider必须自定义一个类继承ContentProvider并实现其中的抽象方法:

              public boolean onCreate():该方法在ContentProvider创建后就会被调用,                                                                  Android开机后,ContentProvider在其它应用第一                                                            次访问它时才会被创建。

             public Cursor query(Uri uri, String[] projection, String selection, String[]                                                   selectionArgs, String sortOrder):该方法用于供外部应用从                                                                                                       ContentProvider中获取数据。

             public Uri insert(Uri uri, ContentValues values):该方法用于供外部应用往                                                                                                        ContentProvider添加数据。

            public int update(Uri uri, ContentValues values, String selection, String[]                                                                           selectionArgs):该方法用于供外部应用更新                                                                                                  ContentProvider中的数据。

           public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于供                                                                                外部应用从ContentProvider删除数据。

          public String getType(Uri uri):该方法用于返回当前Url所代表数据的MIME类型。

                                                                如果操作的数据属于集合类型,那么MIME类型字                                                             符串应该以vnd.android.cursor.dir/开头,

                                                        如果要操作的数据属于非集合类型数据,那么                                                                 MIME类型字符串应该以vnd.android.cursor.item/开头,

    创建自己的ContentProvider步骤:

    ①封装CONTENT_URI(必须是唯一的字符串,常用Contentprovider完全限定名)

        和数据库表的列名,必须为其定义一个叫_id的列,它用来表示每条记录的唯一性。

    public class MyUsers {

              public static final String AUTHORITY  = “com.wissen.MyContentProvider”;

              // BaseColumn类中已经包含了 _id字段和_COUNT字段

              public static final class User implements BaseColumns {

                          public static final Uri CONTENT_URI  =                                                                                         Uri.parse(”content://com.wissen.MyContentProvider”);

                                // 表数据列

                             public static final String  USER_NAME  = “USER_NAME”;

             }

    }

    ②定义自己的MyContentProvider类继承ContentProvider,实现其中的抽象方法

     ③实现SQLiteOpenHelper对数据库的操作,一共②使用. 

    ④在AndroidManifest.xml中配置ContentProvider

    <provider android:name="MyContentProvider"

        android:authorities="包名.类名“/>

    (3)ContentReslover类的介绍

         <1>ContentReslover的作用和特点

                当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,ContentReslover是一个抽象类,不能new出其实例,Context提供了getContentResLover()方法

    <2>ContentReslover的常用方法

          ContentResolver 类提供了与ContentProvider类相同签名的四个方法:

          public Uri insert(Uri uri, ContentValues values):该方法用于往ContentProvider添加数据。

            public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于从ContentProvider删除数据。

            public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):该方法用于更新ContentProvider中的数据。

            public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):该方法用于从ContentProvider中获取数据。

               参数:uri  同上解释

                         projection  要返回的列名组成的数组

                         selecttion  条件字符串,包含占位符

                         selectionArgs  上面占位符要显示的内容组成的数组

                         sortOrder    排列顺序

    这些方法的第一个参数为Uri,代表要操作的ContentProvider和对其中的什么数据进行操作,其实和contentprovider里面的方法是一样的.他们所对应的数据,最终是会被传到我们在之前程序里面定义的那个contentprovider类的方法,假设给定的是:Uri.parse("content://com.bing.providers.personprovider/person/10"),那么将会对主机名为com.bing.providers.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。

    <3>ContentReslover的使用步骤

    ①获取ContentReslover对象

            ContentResolver resolver =  getContentResolver();

    ②指定URI

            Uri uri = Uri.parse("content://com.bing.provider.personprovider/person");

    ③调用contentReslover的方法指定操作

         //添加一条记录

         ContentValues values = new ContentValues();

         values.put("name", "bingxin");

         values.put("age", 25);

         resolver.insert(uri, values);

         //获取person表中所有记录

        Cursor cursor = resolver.query(uri, null, null, null, "personid desc");

        while(cursor.moveToNext()){

        Log.i("ContentTest", "personid="+ cursor.getInt(0)+ ",name="+ cursor.getString(1));

    }

        //把id为1的记录的name字段值更改新为zhangsan

       ContentValues updateValues = new ContentValues();

       updateValues.put("name", "zhangsan");

      Uri updateIdUri = ContentUris.withAppendedId(uri, 2);

      resolver.update(updateIdUri, updateValues, null, null);

      //删除id为2的记录

      Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);

      resolver.delete(deleteIdUri, null, null);

    <4>系统提供的ContentProvider已经封装好的URI

    (4)URI的介绍

         URI叫做统一资源标识符,代表要操作的数据,这样你就可以找到对应的       ContentProvider以及想要的数据.(URI也可以说是一种类似SQL的查询语句)

    URI的格式:

             content://com.example.transportationprovider/trains/122

             该URI可以根据反斜杠来划分为四部分

             content://  :  协议部分类似于http://,不可改变

             com.example.transportationprovider  :  该部分是URI的授权部分,是唯一标识,用来定位ContentProvider.一般定义为Contentprovider的完全限定名,注册时需要用到

             trains/122  :  内部路径部分, trains指向一个集合,一般用表名来表示,"122"为_id.单条数据的标识,如果没有"122"则返回一个数据集,有"122"则返回一条数据

    (5)UriMatcher类的介绍

           因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher和ContentUris 。掌握它们的使用,会便于我们的开发工作。

    UriMatcher类用于匹配Uri,它的用法如下:

    首先第一步把你需要匹配Uri路径全部给注册上,如下:

    //常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码

    UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    //如果match()方法匹配content://com.bing.procvide.personprovider/person路径,返回匹配码为1

    sMatcher.addURI("com.bing.procvide.personprovider", "person", 1);//添加需要匹配uri,如果匹配就会返回匹配码

    //如果match()方法匹配content://com.bing.provider.personprovider/person/230路径,返回匹配码为2

    sMatcher.addURI("com.bing.provider.personprovider", "person/#", 2);//#号为通配符

    switch(sMatcher.match(Uri.parse("content://com.ljq.provider.personprovider/person/10"))) {

              case 1

                        break;

             case 2

                        break;

             default://不匹配

                       break;

    (6)ContentUris类的介绍

           ContentUris类用于操作Uri路径后面的ID部分,它有两个比较实用的方法:

                       withAppendedId(uri, id)用于为路径加上ID部分:

                       parseId(uri)方法用于从路径中获取ID部分:

    (7)监听ContentProvider中数据的变化

    如果ContentProvider的访问者需要知道ContentProvider中的数据发生变化,

    则需要有两个步骤

    ①ContentProvider需要在数据发生变化时调用getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者

    例:

    public class PersonContentProvider extends ContentProvider {

                public Uri insert(Uri uri, ContentValues values) {

                             db.insert("person", "personid", values);

                             getContext().getContentResolver().notifyChange(uri, null);

                }

    }

    ②ContentProvider的访问者必须使用ContentObserver对数据(数据采用uri描述)进行监听,当监听到数据变化通知时,系统就会调用ContentObserver的onChange()方法:

    contentProvider对象调用registerContentObserver(uri, notifyForDescendents, observer);注册监听

    参数说明: URI  要监听数据的URI

                    notifyForDescendents  true/false

                    observer  ContentObserver实例,其中实现了onChange方法

    例:

    getContentResolver().registerContentObserver(Uri.parse("content://com.ljq.providers.personprovider/person"),

                    true, new PersonObserver(new Handler()));

    public class PersonObserver extends ContentObserver{

                public PersonObserver(Handler handler) {

                                  super(handler);

               }

               public void onChange(boolean selfChange) {

                               //此处可以进行相应的业务处理

              }

    }

    (8)操作Android系统短息信息

    (9)操作Android系统通话记录

    (10)操作Android系统联系信息

    (11)操作Android图片信息

    (12)操作Android音频信息

    (13)操作Android视频信息

    相关文章

      网友评论

          本文标题:3.菜单+对话框+数据存储+Content provide

          本文链接:https://www.haomeiwen.com/subject/zcfaqxtx.html