安卓学习记录(1)

来源:互联网 发布:手机淘宝的服务平台 编辑:程序博客网 时间:2024/06/09 19:23
intent 的使用:
跳转 activity
显示 intent:
Intent _intent = new Intent(firstActivity.this, SecActivity.class);
startActivity(_intent);

隐式 intent:
在Manifet 文件内,在目标 Activity 的<intent-filter>标签内添加 action 和 category,当_intent同时匹配 action 和 category 的时候,才會进行跳转(注意是同时匹配。)
e.g.:
<activity  …...>    <intent-filter>        <action android:name= "com.example.activitytest.ACTION_START"></action>        <category android:name="android.intent.category.DEFAULT"/>        <category android:name="sec_activity"/>        <category android:name="sec_activity_02”/>      </intent-filter></activity>
//进行跳转
Intent _intent = new Intent("com.example.activitytest.ACTION_START");_intent.addCategory("sec_activity”);
_intent.addCategory("sec_activity_02”);  startActivity(_intent);
//如果找不到category同时具有sec_activity_02和sec_activity,并且action是com.example.activitytest.ACTION_START,则程序崩溃。
PS:除了category外,还可以添加 data 标签,用来响应 intent
eg.:
..
<intent-filter>    <category android:name="android.intent.category.DEFAULT"/>    <data android:scheme="https”/>  //显示网页的时候,对应的 activity 可以选择响应</intent-filter>
….
显示网页:
Intent _intent = new Intent(Intent.ACTION_VIEW);_intent.setData(Uri.parse("https://www.baidu.com"));startActivity(_intent);
拨打电话
Intent intent = new Intent(Intent.ACTION_DIAL);intent.setData(Uri.parse("tel:10086"));startActivity(intent);
使用 intent 获取下一级活动的数据(A->B,B->A),eg:
A:Intent _intent = new Intent(A.this,B.class);
startActivityForResult(_intent, 1);
在 B 中对应的按钮响应方法或返回按钮响应函数中public void onBackPressed(),实现代码:
Intent _intent = new Intent();
_intent.putExtra("number", “100");
setResult(RESULT_OK,_intent);
finish();
返回 A 时会调用 onActivityResult 函数,
@Overrite
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//requestCode要与之前设置的请求码一致
if (requestCode == 1) {
String test = data.getStringExtra(“number”);
Toast.makeText(Activity01.this, test, Toast.LENGTH_LONG).show();
}
}
 
在 mainfest 文件中,设置 activity 的android:launchMode属性,可控制 activity 的启动方式,
默认是 standard(可重复创建然后启动)
singleTop(当前 activity 位于栈顶,直接使用当前活动,不会创建新的,但如果不是位于栈顶,则还是会创建新的。)
singleTask:上下文只会存在一个该类型的活动,不会重复,并且会把位于该 activity 之上的活动统统出栈
singleInstance:该activity 会位于一个独立栈中,不与其他活动公用一个栈,e.g.:有 A.B.C三个 activity,B是singleInstance模式,即 AC 一个栈,B 是另外一个栈
从A-》B , 然后在B-》C, 此时从C 按返回键会回到 A,在 A 中按返回键会到 B 中,在 B 中按返回键才會退出程序。

打印当前 Activity 名字:
Log.i(”Activity”, getClass().getSimpleName());

控件基本属性:
hint(默认文本)


在当前布局文件(xml 文件)引用其他布局文件:
//title是布局文件title.xml
<include layout="@layout/title" />



隐藏导航栏:requestWindowFeature(Window.FEATURE_NO_TITLE);如果继承AppCompatActivity则无效,可使用:
if (getSupportActionBar() != null){ getSupportActionBar().hide();}
碎片使用
XML 文件:
//left_fragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:layout_gravity="center_horizontal"        android:text="button"        android:id="@+id/id_button"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>
新建LeftFragment类:
public class LeftFragment extends Fragment {    @Override    public View onCreateView(LayoutInflater layoutInflater, ViewGroup parent, Bundle savedInstanceState) {        View v = layoutInflater.inflate(R.layout.left_fragment, parent, false);        return  v;    }}
//main_layout.xml:
…..。。正式使用
<fragment    android:name="com.example.shopins.fragmenttest.LeftFragment"    android:id="@+id/id_left_fragment"    app:layout_constraintLeft_toLeftOf="parent"    app:layout_constraintTop_toTopOf="parent"    app:layout_constraintBottom_toBottomOf="parent"    app:layout_constraintRight_toLeftOf="@+id/id_right_layout"    android:layout_width="0dp"    app:layout_constraintHorizontal_weight="1"    android:layout_height="0dp"></fragment>
…..
碎片替换:
//main_layout.xml文件
<FrameLayout    app:layout_constraintHorizontal_weight="1"    app:layout_constraintBottom_toBottomOf="parent"    app:layout_constraintLeft_toRightOf="@+id/id_left_fragment"    app:layout_constraintRight_toRightOf="parent"    app:layout_constraintTop_toTopOf="parent"    android:id="@+id/id_right_layout"    android:layout_width="0dp"    android:layout_height="0dp”>
<fragment    android:name="com.example.shopins.fragmenttest.RightFragment"    android:id="@+id/id_right_fragment"    android:layout_width="match_parent"    android:layout_height="match_parent”/>
</FrameLayout>
//MainActivity文件
。。。。
AnotherRightFragment newFragment = new AnotherRightFragment();FragmentManager manager = getFragmentManager();FragmentTransaction transaction =  manager.beginTransaction();
//按返回键的时候,返回上一个碎片,一般传入 null
transaction.addToBackStack(null);
transaction.replace(R.id.id_right_layout, newFragment);transaction.commit();
。。。。

//在活动中获取对应碎片实例,调用碎片实例方法:
…..
FragmentManager manager = getFragmentManager();
MyFragment _MyF = (MyFragment)manager.findFragmentById(R.id.fragmentid);
_MyF.func();
…..
//在碎片中获取对应活动,调用活动实例方法:
。。。。。。。
MainActivity activity = (MainActivity) getActivity();
。。。。。。。

另外当碎片中需要使用 Context 对象时,也可以使用 getActivity()方法,因为获取到的活动本身就是一个 Context对象了。


碎片的生命周期:从先到后依次为

  1. onAttach() 当碎片和活动建立关联的时候调用。
  2. onCreateView() 为碎片创建视图(加载布局)时调用。
  3. onActivityCreated() 确保与碎片相关联的活动一定已经创建完毕的时候调用。
  4. onDestroyView() 当与碎片关联的视图被移除的时候调用。
  5. onDetach() 当碎片和活动解除关联的时候调用
在碎片中也可以用onSaveInstanceState()来保持数据。
在 res 目录下用限定符创建对应文件夹,设备可自动加载对应资源:

大小

small

供给小屏幕设备的资源

normal

 供给中等屏幕设备的资源

large

供给大屏幕设备的资源

xlarge

 供给超大屏幕设备的资源

分辨率

ldpi

供给低分辨率设备的资源(120dpi 以下)

mdpi

供给中等分辨率设备的资源(120dpi 到 160dpi) 

hdpi

供给高分辨率设备的资源(160dpi 到 240dpi)

xhdpi

供给超高分辨率设备的资源(240dpi 到 320dpi) 

方向

land

供给横屏设备的资源

port

供给竖屏设备的资源

e.g.:
当 layout 文件中有 main_layout.xml文件,在 res目录下新建 layout-large 文件夹,然后在里面新建 main_layout.xml文件,
那些屏幕被认为是 large 的设备就会自动加载 layout-large 文件夹下的布局,而小屏幕的设备则还是会加载layout 文件夹下的布局。
在 res 目录下,可以看到自动生成的 mdpi 、hdpi 等文件夹
如果希望自定义限定宽度,而不是系统认定的”large”,可使用最小宽度限定符,eg:
加载activity_main布局的时候,先在 res 目录下新建 layout-sw600dp,当程序运行在屏幕宽度大于 600dp 的设备上时,会加载 layout-sw600dp/activity_main 布局,当程序运行在屏幕宽度小于 600dp 的设备上时,则仍然加载默认的layout/activity_main 布局
广播分为有序广播和标准广播(无序)
动态注册实现广播接收器:继承BroadcastReceiver并重写 onReceive(Context context, Intent intent)
e.g.:
//在 manifest 文件内声明权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

….
protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    intentFilter = new IntentFilter();
//网络状态改变的时候接收通知    intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");    _receiver = new NetworkChangeReceiver();    registerReceiver(_receiver, intentFilter);}class NetworkChangeReceiver extends BroadcastReceiver {    public  void onReceive(Context context, Intent intent) {        Toast.makeText(MainActivity.this, "internet changed!!!!", Toast.LENGTH_LONG).show();    }}
….
ps:动态注册后注意要撤销注册



静态注册实现广播:这种方式可以使程序在未启动的情况下就能接收到广播
e.g.:
//新建 XXXX 类(BootCompleteReceiver
public class BootCompleteReceiver extends BroadcastReceiver {    @Override    public  void  onReceive(Context context, Intent intent) {        Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show(); }}
//在 mainfest 文件中添加权限(开机启动)以及进行注册,android.intent.action.BOOT_COMPLETED(系统内置)
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED”/>
<receiver android:name=".BootCompleteReceiver">    <intent-filter>        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter></receiver>
//实现:
….
Intent intent = new Intent("android.intent.action.BOOT_COMPLETED");
sendBroadcast(intent);
…..
自定义广播:
//新建 XXXX 类(BootCompleteReceiver)
public class BootCompleteReceiver extends BroadcastReceiver {    @Override    public  void  onReceive(Context context, Intent intent) {        Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show(); }}
//manifest 文件注册:
<receiver android:name=".BootCompleteReceiver">    <intent-filter >        <action android:name="my_broadcast"/>    </intent-filter></receiver>
//实现:
BootCompleteReceiver  receive = new BootCompleteReceiver();
  
Intent intent = new Intent(“ my_broadcast”)
//只要注册my_broadcast的,都能接收到
sendBroadcast(receive,intent); 
特别:在广播接收器中是不能开启线程的



有序广播:实现方式与自定义相同,区别用sendOrderedBroadcast(第二个参数是一个与权限相关的字符串,可以传入 null )代替sendBroadcast。
ps:因为有序关系,前面的广播接收器可以将广播截断,以阻止其继续传播 ,实现方式是在 onReceive()方法中调用了 abortBroadcast()方法,就表示将这条广播截断,后面的广播接收器将无法再接收到这条广播
ps:如何设置广播顺序?只需要在 manifest 中设置权限优先级,优先级比较高的先收到广播,eg:

<receiver android:name=".MyBroadcastReceiver">

<intent-filter android:priority="100" >
<action android:name="MY_BROADCAST"/>

</intent-filter>

</receiver>

上面的属于系统全局广播,即发出的广播可以被其他任何的任何应用程序接收到

本地广播:只能在该程序内部进行传递。主要通过LocalBroadcastManager进行管理,并提供发送和接收广播的方法
e.g.:
private  MyLocalService _service;private LocalBroadcastManager localBroadcastManager;private IntentFilter intentFilter;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    _service = new MyLocalService();    localBroadcastManager = LocalBroadcastManager.getInstance(this);    Button btn = (Button)findViewById(R.id.id_btn);    btn.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Intent intent = new Intent("My_Local");            localBroadcastManager.sendBroadcast(intent);        }    });    intentFilter = new IntentFilter();    intentFilter.addAction("My_Local");    localBroadcastManager.registerReceiver(_service, intentFilter);}class MyLocalService extends BroadcastReceiver {    @Override    public  void  onReceive(Context context, Intent intent) {        Toast.makeText(MainActivity.this, "this is local message", Toast.LENGTH_LONG).show();    }}
ps:不需要去 manifest 注册

访问 http://developer.android.com/reference/android/Manifest.permission.html 可以查看 Android系统所有可声明的权限

数据持久化:文件存储、数据库存储、sharePreference
文件存取:
//保存
 public void save() {        String data = "Data to save";        FileOutputStream out = null;        BufferedWriter writer = null;        try {
    out = openFileOutput("data", Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(out));            writer.write(data);
        } catch (IOException e) {            e.printStackTrace();
} finally {
            try {
                if (writer != null) { 
writer.close();
                }            } catch (IOException e) {
                e.printStackTrace();            }

}}

//读取
public String load() {        FileInputStream in = null;        BufferedReader reader = null;        StringBuilder content = new StringBuilder();        try {
            in = openFileInput("data");
            reader = new BufferedReader(new InputStreamReader(in));            String line = “”; 
while ((line = reader.readLine()) != null) {                content.append(line);
            }        } catch (IOException e) {
            e.printStackTrace();        } finally {
            if (reader != null) {                try {
                    reader.close();                } catch (IOException e) {
                    e.printStackTrace();                }

}}

        return content.toString();    }

SharedPreferences: 使用键值对的方式来存储数据的。也就是说当保存一条数据的时候,需要给这条数据 供一个对应的键

获取 sharepreferences 对象的三种方法:

1.Context类中的 getSharePreferences()方法,传入两个参数,第一个是文件名,第2个是操作模式(MODE_PRIVATE 和 MODE_MULTI_PROCESS,MODE_PRIVATE表示只有当前程序才能对该文件进行读写)

2.Activity类中的 getPreferences()方法,传入操作模式,默认文件名是当前活动类名
3.PreferenceManager 类中的 getDefaultSharePreferences()方法

得到了 SharedPreferences 对象之后,就可以开始向 SharedPreferences 文件中存储数据了,主要可以分为三步实现。

  1. 调用 SharedPreferences 对象的 edit()方法来获取一个 SharedPreferences.Editor 对象。
  2. 向 SharedPreferences.Editor 对象中添加数据,比如添加一个布尔型数据就使用putBoolean 方法,添加一个字符串则使用 putString()方法,以此类推。
  3. 调用 commit()方法将添加的数据 交,从而完成数据存储操作
    1. e.g.:
      //保存
      SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();editor.putString("keep",text);editor.commit();
      //读取
      TextView v = (TextView)findViewById(R.id.id_textview);SharedPreferences sharedPreferences = getSharedPreferences("data", MODE_PRIVATE);String data = sharedPreferences.getString("keep","null");v.setText(data.toString());
使用数据库:SQLiteOpenHelper
e.g.:
新建数据库工具类(继承SQLiteOpenHelper)
public class MyDatabaseHelper extends SQLiteOpenHelper {    //版本1//    public static final String CREATE_BOOK = "create table Book (" +//            "id integer primary key autoincrement, "//            + "author text, "//            + "price real, "//            + "pages integer, "//            + "name text)";    //版本3    public static final String CREATE_BOOK = "create table Book (" +            "id integer primary key autoincrement, "            + "author text, "            + "price real, "            + "pages integer, "            + "name text, "            + "category_id integer)";    public static final String CREATE_CATEGORY = "create table Category (" + "id integer primary key autoincrement, "            + "category_name text, "            + "category_code integer)";    private Context mContext;    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {        super(context, name, factory, version, null);        mContext = context;    }    @Override    //如果用户是从版本2开始安装程序,那么会创建两个表    public  void onCreate(SQLiteDatabase db) {        db.execSQL(CREATE_BOOK);        db.execSQL(CREATE_CATEGORY);        Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();    }    @Override    //对数据库进行升级时候调用,当 初始化传入的版本号高于之前的,就会升级    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {        switch (oldVersion) {            //如果用户已经安装版本1,现在更新到版本2,只需要再创建第2个表            case  1:                db.execSQL(CREATE_CATEGORY);                break;            //用户从版本2更新到版本3            case 2:                db.execSQL("alter table Book add column category_id integer");                break;            default:        }    }}
//activity 文件
private MyDatabaseHelper myDatabaseHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    myDatabaseHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);    setContentView(R.layout.activity_main);    //创建表    final Button createDatabase = (Button) findViewById(R.id.create_database);    createDatabase.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            myDatabaseHelper.getWritableDatabase();        }    });    //添加    Button addData = (Button) findViewById(R.id.add_data);    addData.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            SQLiteDatabase db = myDatabaseHelper.getWritableDatabase();            ContentValues values = new ContentValues();            // 开始组装第一条数据            values.put("name", "The Da Vinci Code"); values.put("author", "Dan Brown"); values.put("pages", 454);            values.put("price", 16.96);            db.insert("Book", null, values); // 插入第一条数据             values.clear();            // 开始组装第二条数据            values.put("name", "The Lost Symbol"); values.put("author", "Dan Brown"); values.put("pages", 510);            values.put("price", 19.95);            db.insert("Book", null, values);        }    });        //更新数据    Button updateData = (Button) findViewById(R.id.update_data);    updateData.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            SQLiteDatabase db = myDatabaseHelper.getWritableDatabase();            ContentValues contentValues = new ContentValues();            contentValues.put("price", 10.99);            db.update("Book",contentValues,"name = ?", new String[] {                    "The Da Vinci Code"            });        }    });    //删除    Button deleteButton = (Button) findViewById(R.id.delete_data); deleteButton.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            SQLiteDatabase db = myDatabaseHelper.getWritableDatabase();            db.delete("Book", "pages > ?", new String[] { "500" });        }    });    //查询    Button queryButton = (Button) findViewById(R.id.query_data);    queryButton.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            SQLiteDatabase db = myDatabaseHelper.getWritableDatabase();            Cursor cursor = db.query("Book", null, null, null, null, null, null);            if (cursor.moveToFirst()) {                do {                    String name = cursor.getString(cursor.                            getColumnIndex("name"));                    String author = cursor.getString(cursor.                            getColumnIndex("author"));                    int pages = cursor.getInt(cursor.getColumnIndex                            ("pages"));                    double price = cursor.getDouble(cursor.                            getColumnIndex("price"));                    Log.w("MainActivity", "book name is " + name);                    Log.w("MainActivity", "book author is " + author);                    Log.w("MainActivity", "book pages is " + pages);                } while (cursor.moveToNext());                cursor.close();            }        }    });}
//XML 文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <Button        android:id="@+id/create_database"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Create database"        />    <Button        android:id="@+id/add_data"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Add data"        />    <Button        android:id="@+id/update_data"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Update data"        />    <Button        android:id="@+id/delete_data"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Delete data"        />    <Button        android:id="@+id/query_data"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Query data"        /></LinearLayout>
SQL 需要注意大小写,比如 Book 和 book 不一样。
SQLite 支持事务,事务可保证操作全部完成或者操作一步都没有进行。
如何进行事务操作?从SQLiteOpenHelper对象的beginTransaction 方法开始,以SQLiteOpenHelper对象的setTransactionSuccessful 结束。
e.g.:

SQLiteDatabase db = dbHelper.getWritableDatabase();db.beginTransaction(); // 开启事务try {  

db.delete("Book", null, null);

                      //  if (true) {

// 在这里手动抛出一个异常,让事务失败

//  throw new NullPointerException();
  //                      }

ContentValues values = new ContentValues();values.put("name", "Game of Thrones");values.put("author", "George Martin");values.put("pages", 720);
values.put("price", 20.85);
db.insert("Book", null, values);db.setTransactionSuccessful(); // 事务已经执行成功

} catch (Exception e) {
                        e.printStackTrace();
} finally {

db.endTransaction(); // 结束事务

}


内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它 供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性,个人理解,其实就是给外部程序提供访问程序内部数据的接口,令外部程序可以增删改查程序内部的数据

内容提供器的用法一般有两种,一种是使用现有的内容 供器来读取和操作相应程序中的数据,另一种是创建自己的内容 供器给我们程序的数据 供外部访问接口。

类似电话簿、媒体库等都使用了内容提供器

主要使用ContentResolve类,它的增删改查方法接收 Uri 对象,而Uri 对象字符串有两部分构成,权限和路径,
一般权限是包名,路径是表名,前面还需要加上协议。

内容 URI 最标准的格式写法如下:

    content://com.example.app.provider/table1    content://com.example.app.provider/table2
使用内容提供器,需要在 manifest 文件声明权限,eg:自定义内容提供器
<provider android:name="com.example.demo.DatabaseProvider"        android:authorities="com.example.demo.provider" />
使用了<provider>标签来对 DatabaseProvider 这个内容 供器进行注 册,在 android:name 属性中指定了该类的全名,又在 android:authorities 属性中指定了该内容提供器的权限
notification 通知(效果类似push通知):通过 notificationmanager 进行管理,一般通过 getSystemService 获取。e.g.:
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

基本使用:
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
//设置点击通知后跳转的 activity
Intent _itent = new Intent(this, OtherActivity);
PendingIntent pendingIntent = PedingIntent.getActivity(this, 0, _intent,PendingIntent.FLAG_IMMUTABLE);
//初始化 Notification对象,Build 传入 context 对象, setSound这是声音
Notification _notification = new Notification.Build(this).setContentTitle(“title”).setContentText(“text”)
.setContentIntent(pendingIntent).setSmallIcon(R.mipmap.xx)
.setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Basic_tone.ogg")))
.build();
//自定义行为
//设置手机振动,下标0是手机静止时长,下标1是手机振动时长,下标2又是手机静止时长,以此类推,单位是毫秒,该功能需要权限:<uses-permission android:name="android.permission.VIBRATE"/>
long[] vibrates = {0, 1000, 1000, 1000};notification.vibrate = vibrates;
//闪光灯颜色notification.ledARGB = Color.GREEN;//闪光灯暗去,单位:毫秒notification.ledOnMS = 1000;//闪光灯亮起notification.ledOffMS = 1000;//指定通知行为notification.flags = Notification.FLAG_SHOW_LIGHTS;
//或者不自定义,设置全部默认行为。
//notification.defaults = Notification.DEFAULT_ALL;
//传入 id 和 notification 对象
manager.notify(1, _notification)



ps:如果希望点击之后消除通知,需要在对应的活动调用notificationManager.cancel(id).eg:

在上例中OtherActivity:
@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.notification_layout);    NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);    manager.cancel(1);}
获取短信:
private TextView sender;private TextView content;private IntentFilter intentFilter;private MessageReceiver messageReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    sender = (TextView) findViewById(R.id.id_sender);    content = (TextView) findViewById(R.id.id_content);    intentFilter = new IntentFilter();
//设置优先级,保证第一个接收到intentFilter.setPriority(100);
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
messageReceiver = new MessageReceiver();
registerReceiver(messageReceiver, intentFilter);
}
@Override
//activity文件protected void onDestroy() {    super.onDestroy();    unregisterReceiver(messageReceiver);}class  MessageReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        Bundle bundle = intent.getExtras();        Object[] obj = (Object[]) bundle.get("pdus");        SmsMessage[] smsMessage = new SmsMessage[obj.length];        for (int i = 0 ; i < smsMessage.length ; i++) {            smsMessage[i] = SmsMessage.createFromPdu((byte[])obj[i]);        }        String address = smsMessage[0].getOriginatingAddress();        String fullMessage = "";        for (SmsMessage message : smsMessage) {            fullMessage += message.getMessageBody();        }        sender.setText(address.toString());        content.setText(fullMessage.toString());
//拦截通知,不可以继续下发abortBroadcast();
}
}
//manifest 文件设置权限
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
多线程:
1.继承线程类Thread,重写 run
2.实现接口Runnable,重写run
3.在实例化Thread类的时候,定义了一个实现Runnable接口的匿名内部类,
eg:new Thread(new Runnable() {
    @Override    public void run() {     ……..    }}).start();
更新 UI 的时候只能在主线程里更新。
异步消息处理分四部分:Handle,Message,Looper,MessageQueue


4.使用 AsyncTask

  • AsyncTask: 为 UI 线程与工作线程之间进行快速的切换提供一种简单便捷的机制。适用于当下立即需要启动,但是异步执行的生命周期短暂的使用场景。
AsyncTask的使用:继承的时候指定三个范型,
 Params:在执行 AsyncTask 需要传入的参数,可用于后台任务中使用 。 Progress: 后台执行任务时,如果需要在界面显示当前进度,可以设置为进度单位。 Result:当任务结束时,如果需要返回,可以使用这里的范型作为返回类型public class MyAsyncTask extends AsyncTask<Void,Integer,Boolean> {    @WorkerThread    protected Boolean doInBackground(Void... params) {        这里执行所有耗时操作,但是因为不是主线程,所以不能进行界面操作        返回值和继承范型 Result 的类型是一致的。        如果需要更新 UI 元素,比如说反馈当前任务的执行进度,可以调 用 publishProgress(Progress...)方法来完成。        return true;    }    @MainThread    这个方法在后台执行前调用,一般用于进行界面一些初始化操作,比如显示一个进度条    protected void onPreExecute() {    }   @MainThread    protected void onPostExecute(Result result) {       当后台任务执行完毕并通过 return 语句进行返回时,这个方法就很快会被调用。 返 回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些 UI 操作,比如 说 醒任务执行的结果,以及关闭掉进度条对话框等。    }    @MainThread    protected void onProgressUpdate(Integer... values) {        当在后台任务中调用了 publishProgress(Progress...)方法后,这个方法就会很快被调        用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对 UI 进行操 作,利用参数中的数值就可以对界面元素进行相应地更新    }    @MainThread    protected void onCancelled(Result result) {        onCancelled();    }}
使用: new MyAsyncTask().execute();
自定义服务,并有下载功能:
public class MyService extends Service {    private DownloadBinder mBinder = new DownloadBinder();    class DownloadBinder extends Binder {        public void startDownload() {            Log.d("MyService", "startDownload executed");        }        public int getProgress() {            Log.d("MyService", "getProgress executed");            return 0;        }    }    @Override    public  IBinder onBind(Intent intent) {        Log.w("onBind", getClass().getSimpleName());        return mBinder;    }    @Override,如果初始化,则首先执行。    public void onCreate() {        Log.w("onCreate", getClass().getSimpleName());    }    @Override,startService 后调用,如果该服务还没创建,则该方法在 onCreate后调用。    public int onStartCommand(Intent _intent, int flags, int _startID) {        Log.w("onStartCommand", getClass().getSimpleName());        return  super.onStartCommand(_intent, flags, _startID);    }    @Override    public void onDestroy() {        Log.w("onDestroy", getClass().getSimpleName());        super.onDestroy();    }}
使用:
1.先声明一个 ServiceConnection 对象:
private MyService.DownloadBinder downloadBinder;
private final ServiceConnection serviceConnection = new ServiceConnection() {    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        downloadBinder = (MyService.DownloadBinder)service;        downloadBinder.startDownload();        downloadBinder.getProgress();    }    @Override    public void onServiceDisconnected(ComponentName name) {    }};
2.执行执行绑定:
Intent bind = new Intent(this, MyService.class);bindService(bind, serviceConnection,BIND_AUTO_CREATE);
3.接触绑定:
Intent unbind = new Intent(this, MyService.class);unbindService(serviceConnection);
需要声明权限:
<service android:name=".MyService"/>

一种异步、自动停止的服务:IntentService
IntentService: 适合于执行由 UI 触发的后台 Service 任务,并可以把后台任务执行的情况通过一定的机制反馈给 UI。
e.g.:
...
public class MyIntentService extends IntentService {    public MyIntentService() {        super("MyIntentService");    }    @Override    public IBinder onBind(Intent intent) {        return null;    }//    @WorkerThread    protected  void onHandleIntent( Intent intent) {        Log.w("onHandleIntent","Thread id is " + Thread.currentThread().getId());    }}
..
//在 manifest 文件注册权限:
<service android:name=".MyIntentService"/>
使用:
Intent intentService = new Intent(this, MyIntentService.class);
startService(intentService);

延时操作(定时任务):
  1. 开启新线程 

    new Thread(new Runnable(){   

        public void run(){   

            Thread.sleep(XXXX);   

            handler.sendMessage(); //告诉主线程执行任务   

        }   

    }).start 

  2. 利用定时器

    TimerTask task = new TimerTask(){   

        public void run(){   

        //execute the task 

        }   

    };   

    Timer timer = new Timer(); 

    timer.schedule(task, delay); 

    // 

  3. new Handler().postDelayed(new Runnable(){   

        public void run() {   

        //execute the task   

        }   

     }, delay);   

  4. 利用AlarmManager,用于长时间、复杂的任务。

 
HttpsURLConnection的使用。
e.g.:
private static final int SHOW_RESPONSE = 0;private Button sendRequest;private TextView responseText;private Handler handler = new Handler(){    public void handleMessage(Message msg) {        switch (msg.what) {            case  SHOW_RESPONSE:                StringBuilder str = (StringBuilder)msg.obj;                responseText.setText(str.toString());                break;            default:                break;        }    }};@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    sendRequest = (Button)findViewById(R.id.id_send_request);    responseText = (TextView)findViewById(R.id.id_response);    sendRequest.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            sendRequestWithHttpURLConnection();        }    });}public void sendRequestWithHttpURLConnection() {    new Thread(new Runnable() {        @Override        public void run() {            HttpsURLConnection connection = null;            try {                URL url = new URL("https://www.baidu.com");                connection = (HttpsURLConnection)url.openConnection();                connection.setConnectTimeout(8000);                connection.setReadTimeout(8000);                connection.setRequestMethod("GET");                InputStream inputStream = connection.getInputStream();                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));                StringBuilder stringBuilder = new StringBuilder();                String line = "";                while ((line = bufferedReader.readLine()) != null) {                    stringBuilder.append(line);                }                Message message = new Message();                message.what = SHOW_RESPONSE;                message.obj = stringBuilder;                handler.sendMessage(message);            } catch(Exception e) {                e.printStackTrace();            } finally {                if (connection != null) {                    connection.disconnect();                }            }        }    }).start();}

解析 JSON
使用JSONObjecte.g.:
//JSON数据
 [{"id":"5","version":"5.5","name":"Angry Birds"},    {"id":"6","version":"7.0","name":"Clash of Clans"},    {"id":"7","version":"3.5","name":"Hey Day”}]
//jsonData的值打印出来跟上面一致。
private void parseJSONWithJSONObject(String jsonData) {
        try {
            JSONArray jsonArray = new JSONArray(jsonData);            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String id = jsonObject.getString("id");                String name = jsonObject.getString("name");                String version = jsonObject.getString("version");                Log.d("MainActivity", "id is " + id);                Log.d("MainActivity", "name is " + name);
            }        } catch (Exception e) {
            e.printStackTrace();        }

}

添加jar 方式:1.赋值 jar 包到 libs 文件夹下,

2.在 android studio 找到加入的 jar 包,右键选择add as library,然后添加

详细:http://www.cnblogs.com/neozhu/p/3458759.html


使用Json 解析轮子GSON:https://github.com/google/gson

下载地址:http://search.maven.org/#artifactdetails%7Ccom.google.code.gson%7Cgson%7C2.8.1%7C

e.g.:



网络功能轮子:

OkHttp:http://square.github.io/okhttp/

或者https://github.com/square/okhttp
用法:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html

网络编程最佳实践:
//自定义网络工具类
public class HttpService {    public interface HttpCallbackListener {        void onFinish(String response);        void onError(Exception e);    }    public static void sendHttpRequest(final String address, final    HttpCallbackListener listener) {        new Thread(new Runnable() {        @Override        public void run() {            HttpURLConnection connection = null;            try {                URL url = new URL(address);                connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); connection.setDoInput(true); connection.setDoOutput(true);                InputStream in = connection.getInputStream();                 BufferedReader reader = new BufferedReader(new InputStreamReader(in));                StringBuilder response = new StringBuilder();                String line;                while ((line = reader.readLine()) != null) {                    response.append(line);                }                if (listener != null) {                 // 回调onFinish()方法                 listener.onFinish(response.toString());                }            } catch (Exception e) {                if (listener != null) { // 回调onError()方法 
listener.onError(e);                }            } finally {                if (connection != null) {                    connection.disconnect();                }            } }        }).start();    }
}
使用:HttpService.sendHttpRequest(“https://www.baidu.com", new HttpService.HttpCallbackListener() {
    @Override    public void onFinish(String response) {            }    @Override    public void onError(Exception e) {    }});
反向地理编码:使用Geocoding Api
使用 GeoCoder 也提供正向和反向的地理编码功能,但是有 bug:有一定概率地理位置解析失败,所以使用 Geocoding API 比较稳定

https://developers.google.com/maps/documentation/geocoding/。

Geocoding API 中规定了很多接口,其中反向地理编码的接口如下:http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true_or_false

设置获取全局 Content的方法
1.自定义 MyApplication 继承 Application
2.让程序初始化自定义的MyApplication(而不是 Application),需要在 manifest 文件中进行修改注册说明
3.在MyApplication 中重写 onCreate 方法,调用Application的getApplicationContext方法赋值给自定义的static 变量。
e.g.:
//需要在 manifest 文件内,添加注册声明
 public class MyApplication extends Application {        private static Context context;
 @Override        public void onCreate() {
            context = getApplicationContext();        }
        public static Context getContext() {            return context;

}}

ps:可以在自定义的 application 类中,定义一些全局变量。


使用 intent 来传递自定义对象:Serializeble方式和 parcelable 方式
Serializeble方式:
1。自定义对象实现Serializeble
2.获取对象时候intent 调用getSerializableExtra方法获取。
e.g.:
public class Person implements Serializable{
private String name;
        private int age;
        public String getName() {            return name;

}

        public void setName(String name) {            this.name = name;

}

        public int getAge() {            return age;

}

        public void setAge(int age) {            this.age = age;

}}

//使用
Person person = new Person();
    person.setName("Tom");    person.setAge(20);    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);    intent.putExtra("person_data", person);
    startActivity(intent);
//获取对象
Person person = (Person) getIntent().getSerializableExtra("person_data");

parcelable方式:将对象进行分解,分解后的每一个部分都是intent 所支持的数据类型。parcelable比Serializeble的效率要高一点,但更加复杂
e.g.:
public class Person implements Serializable{
private String name;
        private int age;
 public String getName() {            return name;

}

        public void setName(String name) {            this.name = name;

}

        public int getAge() {            return age;

}

        public void setAge(int age) {            this.age = age;

}

@Override        public int describeContents() {

return 0;}

        @Override        public void writeToParcel(Parcel dest, int flags) {

dest.writeString(name); // 写出name

dest.writeInt(age); // 写出age}

public static final Parcelable.Creator<Person> CREATOR = new Parcelable. Creator<Person>() {

            @Override            public Person createFromParcel(Parcel source) {

Person person = new Person();
person.name = source.readString(); //
读取nameperson.age = source.readInt(); // 读取agereturn person;

}

            @Override            public Person[] newArray(int size) {
                return new Person[size];           }

};

}


原创粉丝点击