当前位置:  编程技术>移动开发
本页文章导读:
    ▪content provider 的容易介绍(sdk doc翻译)        content provider 的简单介绍(sdk doc翻译) 内容提供器   内容提供器是用来读取和存储数据,使用它可以将我们自己的数据共享给别人,同时可以读取到别人的数据在别人容许的情况下。他是.........
    ▪ 控件的占空间的比率 layout_weight        控件的占空间的比例 layout_weight layout_weight是LinearLayouts的view布局里一个很重要的值。 所有的view的layout_weight缺省值都是为0,意味着他们只在屏幕上占据它们需要显示的空间大小。 activity.........
    ▪ 模拟器通过需要帐户的代理服务器下网       模拟器通过需要帐户的代理服务器上网 转:http://dev.10086.cn/cmdn/wiki/index.php?doc-view-6074.html 1、参照方法一,设置系统变量,启动模拟器 2、依次进入 settings->Wireless controls->Mobile networks->Ac.........

[1]content provider 的容易介绍(sdk doc翻译)
    来源: 互联网  发布时间: 2014-02-18
content provider 的简单介绍(sdk doc翻译)
内容提供器
   内容提供器是用来读取和存储数据,使用它可以将我们自己的数据共享给别人,同时可以读取到别人的数据在别人容许的情况下。他是唯一个可以在不同的应用程序间共享数据的方式,没有公共的存储区域,所有的android应用程序都可以访问。

    android系统自带一些内容提供器为常用的数据类型,如音乐,视频,图片,联系人资料等,你可以通过android.provider包查看这些东东,你可以通过这些内容提供器查询他们包含的数据(但是你必须要得到其他用户程序的许可)。
   
     如果你想让你的数据可以让别人共享,你必须做两个操作,1.你需要建立你自己的contentProvider(一个系统提供的contentProvider的子类)存储数据,2.你通过别人提供的provider去存储自己的数据(这个provider必须很你需要操作的数据类型一样,且你拥有这个provider写的权利)。

   contentprovider基础
   
    一个contentprovider怎样存储数据,完全有他的开发者控制,但是所有的contentprovider必须实现相同的接口,用来查询内容和返回结果,比如添加数据,修改,和删除。
   
   用户可以通过系统提供的一个接口getContentResolver回去contentResolver对象(在activity中调用这个对象),当你得到这个对象后,
  一般在activity中使用的方法为
  ContentResolver c = getContentResolver();这个时候你就可以和提供contentprovider的应用进行交互了,
  当我们发起一个查询事件时,系统识别contentProvider通过在查询中提供的uri,然后确定这个contentprovider启动并且在运行,android系统在启动的时候就初始化所有的contentprovider对象(自己提供的contentprovider需要在manifest文件中声明,具体做法一会讲)
对一些公共的应用你永远不需要自己去实现(开源软件的好处,省力,省钱,支持开源,但同时也降低了我们程序员的水准),实际上你根本不需要直接和一个contentprovider打交道(除非是自己的),android系统为没个contentprovider提供了一个实例(单例模式),但是它可以和多个contentresolver打交道(线程安全的),线程安全是由contentresolver和contentprovider完成的,我们使用者不比为此担忧。

  数据模式

    contentprovider是按照表的方式公开自己的数据。每一个行是一条记录,每一列是一个具体的值,这里就不举例了,如果连表都不知道的话,建议你还是别存从事软件开发了,免得降低程序员的水准,呵呵,题外话

    在android的中,每一行数据都必须包含一列,列名为"_id",他是表的主键。主键的概念和作用参考数据库方面的书

    每一个查询都返回一个Cursor对象,做过oracle pl/sql编程的可定知道他的意思。cursor对象可以让我们从一行移另一行,一列移动到另一列,可以很方便的读数据。他还提供读取特定类型的数据的方法,如getString,getInteger等方法,前提是你必须知道每个字段所代表的类型。(一会将详细介绍查询结果和cursor对象)

    Uri
    uri的作用是准确的定位我们需要的contentprovider提供的数据,否则就会乱套(不安全的,得带),每一个contentprovider都提供一个公开的uri ,他可以准确的标识一个数据集,一个contentprovider控制多个数据集,通过uri可以准确的标识他们,中的每一个数据集。所有的uri必须以content://开头,content:是作为识别contentprovider的标识。

   如果你自己定义了一个contentprovider,那么你也需要为他建立一个uri,简化他人调用的工作and make future updates cleaner(请大侠解释),android定义content_uri 常量给所有的和平台交互的provider(Android defines CONTENT_URI constants for all the providers that come with the platform)。例如,查询联系的联系人和联系的图片的uri为:
  android.provider.Contacts.Phones.COntent_URI 和android.provider.Contacts.Photos.CONTENT_URI.
uri 对所有和contentprovider交互的用户。每个contentresolver的方法的第一个参数就是uri,他定义了将要和哪个contentprovider的contentresolver进行对话,以及将要对哪个表进行操作。

   查询一个contentprovider
   
    你需要分三步去查询一个contentprovidr

     1.contentprovidr定义的uri
     2.你需要返回的表的列名
     3.这些数据的类型(本人有点疑问)

     如果你要查询某条特定的数据,你还需要制定ID

   生成查询
   
     你可以通过ContentResolver对象的query方法或者Activity.managedQuery方法,这个方法的参数都一样,都返回一个cursor对象,但是managedQuery方法可以让activity管理cursor对象的生命周期,他可以做好多事情,比如,当activity pauses以后,会自动关闭cursor对象。当activity restart的时候,它可以自动去重新查询。你也可以调用activit的startmanagingCursor(Cursor c)方法去管理这个对象。

query方法和managedQuery方法的第一个参数为provider的uri,关于uri上面已经介绍过了,

    android系统提供了一些辅助方法,比如,COntentUris.withAppendedId()和Uri.withAppendedPath()方法,他们可以很方便的为uri添加一个id,两个方法都是静态的,都返回一个uri对象,下面是android 帮助文档中提供的例子

     import android.provider.Contacts.People;
     import android.content.ContentUris;
     import android.net.Uri;
    import android.database.Cursor;

// Use the ContentUris method to produce the base URI for the contact with _ID == 23.
  //Uri myPerson = ContentUris.withAppendedId(People.CONTENT_URI, 23);

// Alternatively, use the Uri method to produce the base URI.
  // It takes a string rather than an integer.
  Uri myPerson = Uri.withAppendedPath(People.CONTENT_URI, "23");

// Then query for this specific record:
Cursor cur = managedQuery(myPerson, null, null, null, null);

query()和managedQuery()方法的参数代表的意思如下:

        参数1:uri。参数2:需要返回的列名,比如_id,number,nember_key等,如果为空,则返回所有列。参数3:相当于sql语句的where条件,比如 “_id” = 12,"_id" = ? 。如果为null的时候,则返回所有列,前提是你的uri是返回全部的uri。参数4:如果参选3中包含形如"_id" = ?的条件,那么此项不能为空。否则此项为空,目的是提供查询速度,让sql语句软解析。参数5:是排序,比如要按照id排序,则为“id desc ”,不需要加order by。详细请查看android api android.content.contentResolver
    
   查询返回的数据
  
    每个查询都会返回o个或者多条记录。不会返回null,而且每行都会包含_id这列,
 
   读取返回的数据

   从cursor中读数据的时候,一定要知道数据的类型,但是你也可以通过getString方法,读取到所有数据,但是返回的对象都是string类型的,在你实际应用中,你还是要转换成真正的类型,所以还是第一次就使用对象的get方法把,你可以使用index或者列名去读数据。好像没有提供直接使用列名读数据的方法,不知道为什么,待解(难道是我没注意到)。
如下:
if (cur.moveToFirst()) {

        String name;
        String phoneNumber;
        int nameColumn = cur.getColumnIndex(People.NAME);
        int phoneColumn = cur.getColumnIndex(People.NUMBER);
        String imagePath;
   
        do {
            // Get the field values
            name = cur.getString(nameColumn);
            phoneNumber = cur.getString(phoneColumn);
          
            // Do something with the values.
            ...

        } while (cur.moveToNext());

    }

如果一个查询返回的是二进制数据,如image或者音乐。那么数据可以直接存在表中,也可以通过一个uri链接到相应内容。使用uri可以获取数据。一般情况下,小数据,如20-50k或者更小的,直接存在数据库,可以通过getBlod()方法到到btye数据。如果table存在的uri,那么你不需要直接打开或者读取这个文件,(不过要有这个权限)。你应该调用ContentResolver.onpenInputStream()获取inputStream对象,然后可以读。

  修改数据

    1.add
    2.updata
    3.batch update
    3.delete
  
   一. 添加数据
       添加数据的第一步,你需要创建一个key-value对象在ContentValues(相当于map,内部实现还是以map实现的,android封装了java的map对象)。数据设置好后,调用contentResolver的insert方法就可以插入了
     insert方法返回的不是我们想象的id类型,而是一个uri对象,代表新插入记录的uri。你可以使用他查询刚才添加的记录。如下:
ContentValues values = new ContentValues();

// Add Abraham Lincoln to contacts and make him a favorite.
values.put(People.NAME, "Abraham Lincoln");
// 1 = the new contact is added to favorites
// 0 = the new contact is not added to favorites
values.put(People.STARRED, 1);

Uri uri = getContentResolver().insert(People.CONTENT_URI, values);


  二. 修改,删除就不说了,基本上差不多,update和delete方法。

  创建一个contentprovider
  
 
  1.创建一个contentProvider子类
  2.定义uri
  3.使用创建的类。打开一个SQLiteDatabase对象。openRendHelper和openWirterHelper方法。
  4.在manifest文件中声明这个类,一定要声明,<provider android:name="com.example.autos.AutoInfoProvider"
          android:authorities="com.example.autos.autoinfoprovider"
          . . . />
</provider>

  实现类里,需要实现的方法有 query,insert update getType oncreate
  格式为 content://xxx.xxx.xxx全部数据,某一条数据 content://xxx.xxx.xxx/id
<provider android:name="com.example.autos.AutoInfoProvider"
          android:authorities="com.example.autos.autoinfoprovider"
          . . . />
</provider>
import java.util.Calendar;
import java.util.Date;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DiaryDbAdapter {

public static final String KEY_TITLE = "title";
public static final String KEY_BODY = "body";
public static final String KEY_ROWID = "_id";
public static final String KEY_CREATED = "created";

private static final String TAG = "DiaryDbAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;

private static final String DATABASE_CREATE = "create table diary (_id integer primary key autoincrement, "
+ "title text not null, body text not null, created text not null);";

private static final String DATABASE_NAME = "database";
private static final String DATABASE_TABLE = "diary";
private static final int DATABASE_VERSION = 1;

private final Context mCtx;

private static class DatabaseHelper extends SQLiteOpenHelper {

DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS diary");
onCreate(db);
}
}

public DiaryDbAdapter(Context ctx) {
this.mCtx = ctx;
}

public DiaryDbAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}

public void closeclose() {
mDbHelper.close();
}

public long createDiary(String title, String body) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_BODY, body);
Calendar calendar = Calendar.getInstance();
String created = calendar.get(Calendar.YEAR) + "年"
+ calendar.get(Calendar.MONTH) + "月"
+ calendar.get(Calendar.DAY_OF_MONTH) + "日"
+ calendar.get(Calendar.HOUR_OF_DAY) + "时"
+ calendar.get(Calendar.MINUTE) + "分";
initialValues.put(KEY_CREATED, created);
return mDb.insert(DATABASE_TABLE, null, initialValues);
}

public boolean deleteDiary(long rowId) {

return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}

public Cursor getAllNotes() {

return mDb.query(DATABASE_TABLE, new String[] { KEY_ROWID, KEY_TITLE,
KEY_BODY, KEY_CREATED }, null, null, null, null, null);
}

public Cursor getDiary(long rowId) throws SQLException {

Cursor mCursor =

mDb.query(true, DATABASE_TABLE, new String[] { KEY_ROWID, KEY_TITLE,
KEY_BODY, KEY_CREATED }, KEY_ROWID + "=" + rowId, null, null,
null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;

}

public boolean updateDiary(long rowId, String title, String body) {
ContentValues args = new ContentValues();
args.put(KEY_TITLE, title);
args.put(KEY_BODY, body);
Calendar calendar = Calendar.getInstance();
String created = calendar.get(Calendar.YEAR) + "年"
+ calendar.get(Calendar.MONTH) + "月"
+ calendar.get(Calendar.DAY_OF_MONTH) + "日"
+ calendar.get(Calendar.HOUR_OF_DAY) + "时"
+ calendar.get(Calendar.MINUTE) + "分";
args.put(KEY_CREATED, created);

return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}

    
[2] 控件的占空间的比率 layout_weight
    来源: 互联网  发布时间: 2014-02-18
控件的占空间的比例 layout_weight
layout_weight是LinearLayouts的view布局里一个很重要的值。 所有的view的layout_weight缺省值都是为0,意味着他们只在屏幕上占据它们需要显示的空间大小。 activity根据这个View的比0大的layout_weight值来划分剩余的空间和其它Views定义的layout_weight也按比例进行空间的划分。 给个例子:假设我们在水平行上有一个文本标签和两个文本编辑框view. 文本标签没有定义layout_weight 值,所以它将占据最小的需要提供的空间. 如果每个文本框view的layout_weight 都被设置为1, 在父布局中的剩余的宽度将被它们平分.如果一个文本view的layout_weight值为2,另外一个是1, 那么剩余空间的三分之一将给第一个文本框,三分之二将给第二个文本框

    
[3] 模拟器通过需要帐户的代理服务器下网
    来源: 互联网  发布时间: 2014-02-18
模拟器通过需要帐户的代理服务器上网

转:http://dev.10086.cn/cmdn/wiki/index.php?doc-view-6074.html

1、参照方法一,设置系统变量,启动模拟器

2、依次进入 settings->Wireless controls->Mobile networks->Access Point Names  
3、设置以下参数: 
- Proxy : your proxy address  
- Port : your proxy port  
- Username : your username if needed, or <Not set>

 Password : your password if needed, or <Not set>

4、设置DNS参数:

Android模拟器默认的地址是10.0.2.3,默认的DNS也是10.0.2.3,对于在家里上网学习Android的人(像我)来讲,一般 电脑的IP都是192.168.1.100之类的,不在同一个网段。所以就会出现电脑可以上网但是模拟器不能上网的情况。其实设置方 法很简单,只要把模拟 器的默认DNS设置成电脑的DNS地址即可。

第一步:adb shell   (进入模拟器的linux系统)

第二步:getprop  (getprop会列出系统当前的各项属性)

第三步:得到模拟器的DNS地址

在结果里可以看到:

[net.dns1]: [10.0.2.3]
[net.dns2]: [10.0.2.4]
[net.dns3]: [10.0.2.5]
[net.dns4]: [10.0.2.6]

第四步:把dns改成我们自己的DNS

setprop net.dns1 192.168.1.1  或者 setprop net.dns1 192.168.0.1

注:一般TP-LINK及D-LINK的无线DNS都是192.168.1.1,有些公司有线DNS默认192.168.0.1;

如果以上两个DNS不好用,请直接使用ipconfig  /all(windows系统) 或者 ifconfig -a(linux/unix系统)命令确认。

大功告成,再去使用模拟器的浏览器的话,你就可以发现你已经可以上网了。


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
jquery iis7站长之家
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3