《第一行代码》个人笔记

第一章

2003年 Andy Rubin等人创办了Android公司
2005年 谷歌收购了这家公司
2008年 谷歌推出了Android系统的第一个版本

1.1.1Android系统架构

Linux内核层

Android基于linux 2.6内核 这层为安卓设备的各种硬件提供了底层驱动

系统运行时层

通过C++为安卓系统提供了特性支持,(如SQLite,OpenGl|ES,Webkit)
包含运行时库
运行时库中包含Dalvik虚拟机

应用框架层

提供了构建应用程序时可能用到的各种api

应用层

一些app

1.1.2 Android 已发布的版本

2008年09月 android 1.0
2011年02月 android 3.0
2011年10月 android 4.0

1.1.3 Android应用开发特色

1.四大组件

Activity
Service
Broadcast Receiver
Content Provider
2.系统控件
3.SQLite数据库
4.地理位置定位
5.多媒体
6.传感器

1.4.2 使用Android 日志工具Log

Log分5个等级

v:verbose 啰嗦
d:debug 调试
i:info 信息
w:warn 警告
e:error 异常

1.4.3 为什么使用Log而不用System.out

日志打印不可控制
打印时间无法确定
不能添加过滤器
日志没有等级区分

第二章

2.2.4 隐藏标题栏

在setContentView之前执行requestWindowFeature(Window.FEATURE_NO_TITLE)

2.2.6 Menu的使用

重写onCreateOptionsMenu()填充menu的布局

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

重写onOptionItemSelected()判断是点击了menu的哪个item 并 进行响应

public boolean onOptionsItemSelected(MenuItem item) {  
    switch (item.getItemId()) {......}
}

2.3显式Intent

直接表明要传递启动目标的activity

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);

2.3.2隐式Intent

1.在AndroidManifest.xml中标签下的下根据和中的内容去匹配代码中action和category是否相同,如果相同这个activity就会响应Intent

<activity android:name=".SecondActivity" >
    <intent-filter>
        <action android:name="com.example.activitytest.ACTION_START" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

2.默认是android.intent.category.DEFAULT
3.每个Intent中只能指定一个action,但却能指定多个 category。

Intent.ACTION_VIEW显示用户需要的数据
Intent.ACTION_DIAL展示拨号盘

Intent intent = new Intent("com.example.activitytest.ACTION_START");
intent.addCategory("com.example.activitytest.MY_CATEGORY");
startActivity(intent)

2.3.4 通过Intent传递数据

1.通过intent.putExtra()传递

String data = "Hello SecondActivity";
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("extra_data", data);
startActivity(intent);
Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Log.d("SecondActivity", data);

2.通过startActivityForResult 和 OnActivityResult 传递

第一个参数是requestCode,即开启activity时候输入的请求码
第二个参数resultCode,即我们在返回数据时传入的处理结果
第三个参数data,即携带这返回数据的Intent

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent, 1);
Intent intent = new Intent();
intent.putExtra("data_return", "Hello FirstActivity");
setResult(RESULT_OK, intent);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case 1:
    if (resultCode == RESULT_OK) {
        String returnedData = data.getStringExtra("data_return");
        Log.d("FirstActivity", returnedData);
    }
    break;
    default:
    }
}

2.4 Activity的生命周期

1.返回栈

Android是使用任务来管理Activity的,栈是一种后进先出的数据结构

2.活动状态

1.运行状态
2.暂停状态
3.停止状态
4.销毁状态

3.Activity的生存期

onCreate()
onStart()
onResume()
onPause()
onStop()
onDestory()
onRestart()

4.三种生存期

1.完整的生存期

onCreate和onDestory之间所经历的就是完整的生存期

2.可见生存期

onStart和onStop之间所经历的就是可见生存期

3.前台生存期

onResume和onPause之间所经历的就是前台生存期

2.4.5活动被回收了怎么办

1.在onSaveInstanceState中保存
2.在onCreate非空判断savedInstanceState 恢复原来的属性数值

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    String tempData = "Something you just typed";
    outState.putString("data_key", tempData);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(TAG, "onCreate");
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    if (savedInstanceState != null) {
        String tempData = savedInstanceState.getString("data_key");
        Log.d(TAG, tempData);
    }
……
}

2.5 Activity的启动模式

1.standard

默认的启动模式,每当启动一个新的activity,他就会在返回站中入栈,并处于栈顶位置

2.singleTop

在启动activity时候如果发现返回站的栈顶已经是该activity,则认为可以直接使用它,不会再创建他的activity实例了

3.singleTask

每次启动该activity时系统首先会在返回站中监查是否存在该activity的实例,如果发现已经存在则直接使用该实例,并把在这个activity智商的所有活动统统出栈,如果没有发现就会创建一个新的activity实例

4.singleInstance

activity会启用一个新的返回站来管理这个activity

第四章

4.2.2 动态添加fragment

1.创建待添加的fragment实例
2.用getFragmentManager()获取FragmentManager
3.用beginTransaction()开启一个事务
4.通过replace()向容器内替换Fragment
5.用commit()提交事务

4.2.3 在Fragment中模拟返回栈

addToBackStack()

4.2.4 Fragment和Activity之间进行通信

方法1:findFragmentById()

RightFragment rightFragment = (RightFragment) getFragmentManager()
.findFragmentById(R.id.right_fragment);

方法2:getActivity()

MainActivity activity = (MainActivity) getActivity();

4.3.1 Fragment的状态

1.运行状态
2.暂停状态
3.停滞状态
4.销毁状态

4.3.2 Fragment的回调

1.onAttach() 当fragment和activity建立关联的时候
2.onCreateView() 为Fragment创建视图
3.onActivityCreated() 确保和fragment相关联的activity一定已经创建完毕
4.onDestroyView() 当与fragment关联的视图被移除
5.onDetach() 当fragment和activity接触关联

4.3.3 Fragment和Activity全部生命周期

1.onAttach
2.onCreate
3.onCreateView
4.onActvityCreated
5.onStart
6.onResume
7.onPause
8.onStop
9.onDestoryView
10.onDestroy
11.onDetach

4.4.1 使用限定符

限定符描述
smail小屏幕
normal中屏幕
large大屏幕
xlarge超大屏幕
ldpi低分辨率 120dpi以下
mdpi中分辨率 120dpi=160dpi
hdpi高分辨率 160dpi-240dpi
xdpi超高分辨率 240dpi-320dpi
land横屏
port竖屏

4.4.2 使用最小宽度限定符

例如:layout-sw600dp

第五章

5.1广播机制简介

广播分为有序广播和无序广播
标准广播是一种异步执行广播
有序广播是一种同步执行广播

5.2.1 动态注册监听网络变化

注册广播有两种

1.动态注册 在代码中注册

public class MainActivity extends Activity {
    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(networkChangeReceiver, intentFilter);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
    }
    class NetworkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "network changes",
            Toast.LENGTH_SHORT).show();
        }
    }
}

2.静态注册 在AndroidManifest.xml注册

public class BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
    }
}
<receiver android:name=".BootCompleteReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

注意:

1.动态注册的广播一定要取消注册,在onDestory方法中调用unregisterReceiver实现
2.在onReceive方法中,通过getSystemService方法得到ConnectivityManager的实例
再调用getActivieNetworkInfo得到NetworkInfo实例,通过isAvailable判断是否有网络

5.2.2 静态注册实现开机启动

1.安卓启动后会发出android.intent.action.BOOT_COMPLETED的广播
2.需要添加android.permission.RECEIVE_BOOT_COMPLETED权限

注意:

广播接收器中是不允许开启线程的

5.3.2 发送有序广播

1.sendBroadcast改为sendOrderedBroadcast即可
2.android:priority给广播接收器设置了优先级
3.在onReceive方法中调用abortBroadcast方法就可以拦截广播

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter android:priority="100" >
        <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
    </intent-filter>
</receiver>

5.4 使用本地广播

使用LocalBroadcastManager来对广播进行管理

1.通过LocalBroadcastManager的getInstance得到实例
2.实例调用registerReceive方法是回调
3.LocalBroadcastManager的sendBroadcast发送广播

5.6 Git时间.初始版本控制工具

1.配置用户

git config –global user.name “Tony”
git config –global user.email “tony@gmail.com”

2.创建仓库

在目录下 git init

第六章

6.1 持久化技术简介

有三种方式

1.文件存储
2.SharePreference
3.数据库存储

6.3.1 获取sp

有三种方法

1.Context.getShearedPreferences
2.Actvity.getShearedPreferences
3.getDefaultSharedPreferences

存储实现步骤

1.sp.edit
2.editor.putXXX()
3.commit()

6.4 SQLite 数据库存储

通过实现SQLiteOpenHelper创建和升级数据库

query方法参数对应SQL部分描述
tablefrom table_name指定查询的表名
columnsselect columnl,columnl2指定查询的列名
selectionwhere column = value指定where的约束条件
selectionArgs为where中的占位符提供具体的值
groupBygroup by column指定需要group by的列
havinghaving column = value对group by后的结果进一步的约束
orderByorder by columnl,columnl2指定查询结果的排序方式

6.5 使用 SQL 操作数据库

注意:除了查询数据的时候调用的是 SQLiteDatabase 的 rawQuery()方法, 其他的操作都是调用的 execSQL()方法。

添加数据的方法如下:

db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",
new String[] { "The Da Vinci Code", "Dan Brown", "454", "16.96" });
db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",
new String[] { "The Lost Symbol", "Dan Brown", "510", "19.95" });

删除数据的方法如下:

db.execSQL("delete from Book where pages > ?", new String[] { "500" });

更新数据的方法如下:

db.execSQL("update Book set price = ? where name = ?", new String[] { "10.99",
"The Da Vinci Code" });

查询数据的方法如下:

db.rawQuery("select * from Book", null);

6.5.1 使用数据库事务

1.beginTransactioon开启事务
2.setTransactionSuccessful表示事务已经执行
3.在finally执行 endTransacitoon结束事务

第七章

7.1内容提供者

使用内容提供者事Andrid实现跨程序共享数据的标准方式

7.2.1 ContentReslver的基本用法

可以通过Context中的getContentResolver()方法获取实例

insert()添加
update()更新
delete()删除
query()查询

ContentResolver中的增删改查都不是用表名参数,而是使用Uri代替
他主要由2部分组成,权限和路径
权限是用于对不同应用程序做区分的,采取包名的方式命名
路径使用用于对同一应用程序不同的表做区分的

例子 com.example.app.provoder/table

我们还需要在字符串的头部加上协议声明

content://com.example.app.provider/table1

query方法参数对应SQL部分描述
urifrom table_name指定查询某个应用程序下的某一张表
projectionselect columnl,columnl2指定查询的列名
selectionwhere column = value指定where的约束条件
selectionArgs为where中的占位符提供具体的值
orderByorder by columnl,columnl2指定查询结果的排序方式
//查询联系人数据
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
while(cursor.moveToNext()){
    //获取联系人姓名
    String displayName = cursor.getString(cursor.getColumIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
    //获取联系人电话
    String number = cursor.getString(cursor.getColumIndex(ContactsContract.CommondATAkINDS.Phone.NUMBER));
}

别忘了加入android.permission.READ_CONTACTS权限

7.3.1创建内容提供者的步骤

public class MyProvider extends ContentProvider{
    @override
    public boolean onCreate(){
        return false;
    }
    @override
    public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder){
        return null;
    }
    @override
    public Uri insert(Uri uri,ContentValues values){

    }
    @override
    public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs){
        return 0;
    }
    @override
    public int delete(Uri uri,String selection,String[] selectionArgs){
        return 0;
    }
    @override
    public String getType(Uri uri){
        return null;
    }
}

在这六个方法中
onCreate()

初始化内容提供者的时候调用,通常会在这里完成对数据库的创建和升级等操作,返回true表示内容提供者初始化成功,返回false则表示失败.注意,只有当存在ContentResolver尝试访问我们程序中的数据时,内容提供者才会被初始化.

query()

从内容提供者查询数据,使用uri参数来确定查询哪张表,projection参数用于确定查到哪些列,selection和selectionArgs参数用于约束查询哪些行,sortOrder参数用于对结果进行排序,查询的结果存放在Cursor对象中返回.

insert()

向内容提供者中添加一条数据,使用uri参数来确定添加到哪张表,待添加的数据保存在values参数中.添加完成后,返回一个用于表示这条新纪录的URI.

update()

更新内容提供者已有的数据,使用uri参数来确定更新哪一张表中的数据,新数据保存在values参数中,selecion和selectionArgs参数用于约束更新哪些行,受影响的行数将作为返回值返回.

delete()

从内容提供者中删除数据,使用uri参数来确定删除哪一张表中的数据,selection和selectionArgs参数用于约束删除哪些行,被删除的行数将作为返回值返回.

getType()

根据传入的内容URI来返回相应的MIME类型

第八章

8.1使用通知

通知(Notification)
发出一条通知后,手机最上方的状态栏中会显示一个通知的图标,下拉状态栏胡可以看到通知的详细内容

8.1.1通知的基本用法

1.创建NotificationManager对象

NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

2.创建Notification 对象

1.第一个参数是通知的图标
2.第二个是弹出通知的内容
3.第三个是制定通知被创建的时间,以毫秒为单位

Notification notification = new Notification(R.drawable.icon,"This is ticker text",System.currentTimeMillis());

3.设置通知栏内通知的布局

1.第一个参数是context
2.第二个参数是制定通知的标题的内容
3.第三个参数用于制定通知的正文内容
4.第四个是PendingIntent(后面讲解)

notification.setlatestEventInfo(context,"This is content title","This is content text",null);

4.显示出来

1.第一个参数是id,相同id的通知会覆盖
2.第二个参数是Notification对象

manager.notify(1,notification);

PendingIntent

他主要提供了几个静态方法获取PendingIntent实例比如:

getActivity()
getService()
getBroadcast()

这几个参数都是相同的

第一个参数是Context
第二参数一般不用传递0即可
第三个参数是一个Intent对象
第四个参数用于确定PendingIntent的行为

public class MainActivity extends Activity implements OnClicklistener{
    ......
    @override
    public void onClick(View view){
        switch(v.getId()){
            case R.id.send_notice:
                NotificationManager manager =(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
                Notification notification = new Notification(R.drawable.ic_launcher,"This is ticker tex",System.currentTimeMillis());
                Intent intent = new Intent(this,NotificationActivity.class);
                PendingIntent pi = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_CANCEL_CURRENT);
                notification.setLatestEventInfo(this,"This is content title","This is content text",pi);
                manager.notify(1,notification);
                break;
            default:
                break;
        }
    }
}

让通知消失

参数为notification的id

manager.cancel(1);

8.1.2 通知的高级技巧

播放音频 sound

Uri soundUri = Uri.fromFile(new File("/system/media/audio/ringtones/Basic_tone.ogg"));
notification.sound = soundUri;

播放视频 vibrates

第一个参数 振动延迟
第二个参数 震动时间
第三个参数 停止震动时间
第四个参数 再次震动时间

long[] vibrates = {0,1000,1000,1000};
notification.vibrate = vibrate;

呼吸灯

iedARGB 用于控制LED的颜色
ledOnMS 用于控制亮起的时间
ledOffMS 用于指定灯暗去的时间
flag 用于指定通知的一些行为

notification.ledARGB  = Color.Green;
notification.ledOnMS = 1000;
nofitication.ledOffMS = 1000;
notification.flags = nofitication.FLAG_SHOW_LIGHTS;
//默认设置
notification.defaults = Notification.DEFAULT_ALL;

8.4播放音频

通过MediaPlayer类实现

方法名功能描述
setDataSource()设置要播放的音频文件的位置
prepare()在开始播放之前调用这个方法完成准备工作
start()开始或者继续播放音频
pause()暂停播放音频
reset()将MediaPlayer 对象重置到刚刚创建的状态
seekTo()从指定的位置开始播放音频
stop()停止播放音频.调用这个方法后的MediaPlayer对象无法在播放音频;
release()释放掉与MediaPlayer对象相关的资源
isPlaying()判断当前MediaPlayer是否正在播放音频
getDuration()获取载入的音频文件的时长

8.4.2 播放视频

通过VideoView实现

方法名功能描述
setVideoPath()设置要播放的视频文件的位置
start()开始或者继续播放视频
pause()暂停播放视频
resume()将视频重头开始播放
seekTo()从指定的位置开始播放视频
isPlaying()判断当前是否正在播放视频
getDuration()获取载入的视频文件的时长

第九章

9.1服务是什么

服务(Service)是Android中实现程序后台运行的解决方案

9.2.1

第一种 继承Thread

class MyThread extends Thread{
    @override
    public void run(){
        //具体逻辑
    }
}

第二种 实现Runnable

class MyThread implements Runnable{
    @override
    public void run(){
        //具体逻辑
    }
}

9.2.2 在子线程中更新UI

1.通过handler

9.2.3 解析异步消息处理机制

1.Message
实在线程之间传递的消息,它可以在内部携带少量的消息(what arg1 arg2 obj)
2.Handler
处理者 主要用于发送和处理消息

1.sendMessage()方法发送消息
2.handleMessage()方法处理消息

3.messageQueue
消息队列 等待被处理 每个线程只会有一个队列
4.Looper
MessageQueue的管家 负责从队列里面取出传递给Handler的handleMessage()方法

9.2.4使用AsyncTask

创建子类继承它,可以指定三个泛型参数

1.params

在执行AsyncTask时需要传入的参数,可用于在后台任务中使用

2.Progress

后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位

3.Result

当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型

class DownloadTask extends AsyncTask<Void,Integer,Boolean>{

}

经常要去重写的方法

1.onPreExecute()

这个方法会在后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比如显示进度条

2.doInBackground(Param…)

所有代码会在子线程运行,根据第一个参数类型进行返回

3.onProgressUpdate(Progress…)

挡在后台任务调用了publishProgress(Progress…)方法后,这个方法就会很快被调用,主要对UI进行修改

4.onPostExecute(Result)

当后台任务执行完毕并通过return返回时,这个方法就很快会被调用,做一些UI操作

执行这个Task

new DownloadTask().execute();

9.3.1定义一个服务

注:别忘了在配置清单注册Service

public class MyService extends Service{
    @override
    public IBinder onbind(Intent intetn){
        reutnr null;
    }
    @override
    public void onCreate(){
        super.onCreate();
    }
    @override
    public int onStartCommand(Intent intent,int flags,int startId){
        return super.onStartCommand(intent,flags,startId);
    }
    @Override
    public void onDestory(){
        super.onDestory();
    }
}

1.onCreate()会在服务创建的时候调用
2.onStartCommand()会在服务开启的时候调用
3.onDestory()会在服务销毁的时候调用

9.3.2 启动和停止服务

1.stopService()
2.stopSelf()

9.3.3 活动和服务进行通信

1.创建一个专门的对象继承Binder

private ServiceConnection connection = new new ServiceConnection(){
    @Override
    public void onServiceDisconnected(ComponentName name){

    }
    @Override
    public void onServiceConnected(CmponentName name,IBinder service){
        downloadBinder = (MyService.DownloadBinder)service;
        downloadBinder.startDownload();
        downloadBinder.getProgress();
    }
};

onServiceConnected()和onServiceDisConnected()这两个方法分别会在活动与服务成功绑定以及接触绑定的时候调用
绑定服务第三个参数BIND_AUTO_CREATE表示在绑定服务后直接自动创建服务但是onStartCommand()方法不会执行

9.4服务的生命周期

1.每个服务都只会存在一个实例,不管调用多少次startService()只需要调用一次stopService()或者stopSelf(),服务就会停止下来了
2.bindService()后如果服务没有创建国,onCreate()方法会优先于onBind()执行
3.bindService()执行后调用unbindService(),那么onDestory()也会执行
4.一个服务只要被启动或者被绑定了之后,就会一直处于运行状态,必须要让以上两种条件同时不满足,服务才能被销毁,所以这种时候同时调用stopService()和()方法,onDestory()才会执行

9.5.1 使用前台服务

执行notification的startForeground(1,notification)

9.5.2 使用IntentService

与Service区别是每次执行完都会关闭线程
实现onHandleIntent()这个抽象方法,他会在子线程执行

9.6 后台执行的定时任务 Alarm机制

AlarmManager来实现

AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE)
long triggerAtTime = SystemClock.elapsedRealtime()+10*1000;
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pendingIntent);

第一个参数用于指定AlarmManager的工作类型

1.ELAPSED_REALTIME 从系统开机开始算
2.ELAPSED_REALTIME_WAKEUP 从系统开机开始算,并且可以唤醒CPU
3.RTC 从1970年1月1日0点开始
4.RTC_WAKEUP 从1970年1月1日0点开始算,并且可以唤醒cpu
通过SystemClock.elapsedRealtime()可以获取到系统开机至今所经历的时间的毫秒数
通过SystemClock.currentTimeMillis()可以获取到1970年1月1日0点至今所经历的时间的毫秒数

第二个参数是定时任务触发的时间
第三个参数是PendingIntent,一般会通过getBroadcast()方法获取

long triggerAtTime = System.currentTimeMillis()+10*1000;
manager.set(AlarmManager.RTC_WAKEUP,triggerAtTime,pendingIntent)

完整例子

public class LongRunningService extends service{
    @Override
    public IBinder onBind(Intent intent){
        return null;
    }
    @Override
    public int onStartCommand(Intent intent,int flags,int startId){
        new Thread(new Runnable(){
            @Override
            public void run(){
                //打印
            }
        }).start();
        AlarmManager manager = (AlarmManager)getSystemService(ALARM_SERVICE);
        int anhour = 60*60*1000;
        long triggerAtTime = SystemClock.elapsedRealtime()*anHour;
        Intent i = new Intent(this,AlarmReceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(this,0,i,0);
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pi);
        return super.nStartCommand(intent,flags,startId);
    }
}
public class AlarmReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context,Intent intent){
        Intent i = new Intent(context,LongRunningService.class);
        context.startService(i);
    }
}

注:Android4.4版本开始,Alarm任务的触发时间将会变得不确定,将set()换成setExact()方法即可

第十章

10.1 WebView的用法

1.getSettings(); 设置一些浏览器的属性
2.setJavaScriptEnable(); 让WebView支持JavaScript脚本
3.loadUrl(); 加载该网页

10.2.1 使用HttpURLConnection

HttpURLConnection connection = null;
try{
    URL url = new URL("http://www.baidu.com");
    connection = (HttpURLConnection)url.openConnection();
    connection.setRequestMethod("GET");
    connection.setConnectTimeout(8000);
    connection.setReadTimeout(8000);
    InputStream in = connection.getInputStream();
    //下面对获取到的输入流进行读取
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    StringBuider response = new StringBuilder();
    String line;
    while((line = reader,readline())!=null){
        response.append(line);
    }
    Message message = new Message();
    message.what = SHOW_RESPONSE;
    //将服务器返回的结果存放到Message中
    message.obj = response.toString();
    handler.sendMessage(message);
} catch(Exception e){
    e.printStackTrace();
} finally {
    if(connection != null){
        connection.disconnect();
    }
}

10.2.2 使用HttpClient

HttpURLConnection connection = null;
try{
    HttpClient httpClient = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet("http://www.baidu.com");
    HttpResponse httpResponse = HttpClient.execute(httpGet);
    if(httpResponse.getStatusLine().getStatusCode() == 200){
        HttpEntry entity = httpResponse.getEntry();
        String response = EntityUtils.toString(entry,"UTF-8");
        Message message = new Message();
        message.what = SHOW_RESPONSE;
        //将服务器返回的结果存放到MESSAGEMessage message = new Message();
        message.what = SHOW_RESPONSE;
        //将服务器返回的结果存放到Messagemessage.obj = response.toString();
        handler.sendMessage(message);
    }
} catch(Exception e){
    e.printStackTrace();
} finally {
    if(connection != null){
        connection.disconnect();
    }
|

12.2.1 光照传感器的用法

SensorManager senserManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
Sensor sensor = senserManager.getDefaultSensor(Sensor.TYPE_LIGHT);
SensorEventListener listener = new SensorEventListener(){
    @Override
    public void onAccuracyChanged(Sensor sensor,int accuracy){
        //values 数组中第一个下表的值就是当前的光照强度
        float value = event.values[0];
    }
    @Override
    public void onSensorChanged(){

    }
}

12.3.2 模仿微信摇一摇

SensorManager senserManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
Sensor sensor = senserManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
senserManager.registerListener(listener,sensor,SensorManager.SENSOR_DELAY_NORMAL);
private SensorEventListener listener = new SensorEventListener(){
    @Override
    public void onSensorChanged(SensorEvent event){
        //加速度可能会是负,所以要用绝对值
        float x = Math.abs(event.values[0]);
        float y = Math.abs(event.values[1]);
        float z = Math.abs(event.values[2]);
        if(x>15||y>15||z>15){
            //认为用户摇动了手机
        }
    }
}

第十三章

13.1 全局获取Context的技巧

public void onCreate(){
    context = getApplicationContext();
}
public static Context getContext(){
    return context;
}

MyApplication.getContext();//获取到Context
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值