《第一行代碼》---Android 啃完,學(xué)習(xí)筆記

#Android 基礎(chǔ)知識(shí)點(diǎn)總結(jié)

----------

##1.adb - android debug bridge

-adb start-server -----開(kāi)啟adb服務(wù)

-adb kill-server -----停止adb服務(wù)

-adb push 本地路徑 手機(jī)路徑 -----將文件導(dǎo)入手機(jī)

-adb pull 手機(jī)路徑 本地路徑 -----導(dǎo)出

-adb logcat -----查看Log

-adb install [-r] [-s] 全路徑/xxx.apk

-r 重新安裝該程序,保存數(shù)據(jù)

-s 安裝在SD卡內(nèi),而不是設(shè)備內(nèi)部存儲(chǔ)

-adb uninstall [-k] 全路徑/xxx.apk

-k 不刪除程序運(yùn)行所產(chǎn)生的數(shù)據(jù)和緩存目錄

-adb remount -----重新掛載文件系統(tǒng)

-adb reboot -----重啟手機(jī)

-adb reboot recovery -----重啟到Recovery界面

-adb reboot bootloader -----重啟到bootloader界面

-adb devices -----列出所有設(shè)備名稱(chēng)或IP

-adb -s IP install 全路徑-apk

-adb shell -----掛載到Linux空間

-netstat -ano ---查看進(jìn)程 (協(xié)議??本地地址 外部地址??狀態(tài)???PID)

進(jìn)入Linux空間后就好玩:

ls ---查看當(dāng)前路徑下的文件

ls -l ---查看文件的具體信息

ps ---查看當(dāng)前運(yùn)行進(jìn)程

netstat -ano ---查看占用端口號(hào)的進(jìn)程

monkey 1000;---猴子測(cè)試 測(cè)試整個(gè)系統(tǒng);1000代表數(shù)量

monkey -p 包名 數(shù)量--- 測(cè)試某個(gè)應(yīng)用程序運(yùn)行數(shù)量后,會(huì)不會(huì)爆

cd .. ---返回上級(jí)目錄

cat xxx.xml ---查看xml文件

sqlite3 xxx.db ---進(jìn)入后

.help 查看幫助

.tables 查看所有表名

.quit 退出

**可以使用sql語(yǔ)句操作表

##2.UI(臉蛋)

1. 四種基本布局:

#LinearLayout#---線性布局

orientation:vertical豎直, horizontal 水平

gravity:指定子布局位置

layout_gravity:指定當(dāng)前控件與父布局的相對(duì)位置

layout_weight:出去已經(jīng)分配的具體屏幕大小,將剩余的屏幕大小按權(quán)重分配(自己的理解)

#RelativeLayout#---相對(duì)布局

初始位置:在屏幕左上角

容易忘記:layout_above="@id/xx"????????????在 xx控件上

layout_below="@id/xx"????????????在 xx控件下

layout_toRightOf="@id/xx"????????在 xx控件右邊

layout_alignParentRight="true"????在父窗體右邊

layout_centerInParent="true"???在父窗體正中間

#FrameLayout#---幀布局、

特點(diǎn):一層層覆蓋

不好玩,用來(lái)被替換的布局,當(dāng)使用碎片fragment來(lái)布局UI的時(shí)候,framelayout里面存放一個(gè)fragment

#TableLayout#---表格布局

基本不用

子控件 中無(wú)法指定寬度,使用 stretchColumns="1";

合并單元格: layout_span="2";

2. 常見(jiàn)控件:

#TextView#

textSize

textColor????#ARGB??a:透明度 r:red g:green b:blue

singleLine???true??單行顯示

maxLines?????多行顯示

#Button#

四種點(diǎn)擊事件:

第一種:通過(guò)給控件添加onclick屬性,然后進(jìn)到 activity中 去添加方法

添加方法時(shí),方法的簽名也是固定的.(google不推薦使用)

andorid:onclick="xxx"

public void xxx(View v){

}`

第二種:給控件添加id , 然后 在activity中拿到 控件,然后 給控件添加onclick時(shí)間的監(jiān)聽(tīng)器

使用匿名內(nèi)部類(lèi)的寫(xiě)法:

`android:id="@+id/xxx"

xxx = (Button) findViewById(R.id.xxx);

xxx.setOnClickListener(new OnClickListener(){

public void onClick(View v){

}

});

第三種:實(shí)際上與第二種一樣, 只是換成了 內(nèi)部類(lèi)的寫(xiě)法.寫(xiě)個(gè)類(lèi)去 實(shí)現(xiàn) Onclick接口

第四種:讓activity類(lèi)去實(shí)現(xiàn) onclicklistner接口最終通過(guò) switch...case去判斷到底點(diǎn)擊的是哪個(gè)控件.

`android:id="@+id/xxx"

xxx = (Button) findViewById(R.id.xxx);

xxx.setOnClickListener(this);

public void onClick(View v){

int id = v.getId();

switch(id){

case R.id.xxx:

break;

default:

break;

}

}

#EditText#

hint

maxLines

inputType

et_content =(EditText) findViewById(R.id.et_content);

String et_content = et_content.getText().toString.trim();

if(TextUtils.isEmpty(et_content)){

Toast.makeText("","",Toast.Length_SHORT).show();

return;

}

#imageView#

src

ImageView.setImageResource(R.drawable.xxx);

好玩的:實(shí)現(xiàn)圖片輪播

自己見(jiàn)一個(gè)xml文件:

/animation-list>`

'ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);

rocketImage.setBackgroundResource(R.drawable.rocket_thrust);

rocketAnimation = (AnimationDrawable) rocketImage.getBackground()

;

rocketAnimation.start();

#RadioGroup#

eg:

android:id="@+id/rg"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

android:layout_width="0dip"

android:layout_weight="1"

android:layout_height="wrap_content"

android:text="男"

android:id="@+id/rb_male"

/>

android:layout_width="0dip"

android:layout_weight="1"

android:layout_height="wrap_content"

android:text="女"

android:id="@+id/rb_female"

/>

獲取屬性值:

if(rg.getCheckedRadioButtonId() == R.id.rb_male){

sex = "male";

}else{

sex = "female";

}

'

#ProgressBar#

max

progress

重要設(shè)置樣式:

style="?android:attr/progressBarStyleHorizontal"

#VideoView#??????????播放音頻視頻,底層是SurfaceView 和 mediaPlayer的結(jié)合。

vv = (VideoView) findViewById(R.id.vv);

// 設(shè)置要

vv.setVideoPath("/mnt/sdcard/lala.3gp");

//mediaController --- 媒體控制器

MediaController mc = new MediaController(this);

mc.setAnchorView(vv);

vv.setMediaController(mc);???// 成功的將MediaController與vv關(guān)聯(lián)起來(lái)

vv.start();

#SurfaceView#

sv = (SurfaceView) findViewById(R.id.sv);

try {

mPlayer = new MediaPlayer();

mPlayer.reset();

mPlayer.setDataSource("/mnt/sdcard/lala.3gp");

mPlayer.prepare();

} catch (Exception e) {

e.printStackTrace();

}

sp = getSharedPreferences("config", 0);

// surfaceHodler --- 界面的持有器,持有者

sv.getHolder().addCallback(new Callback() {

//surface銷(xiāo)毀了

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

System.out.println("銷(xiāo)毀了 ");

Editor editor = sp.edit();

editor.putInt("position", mPlayer.getCurrentPosition());

editor.commit();

mPlayer.stop();

}

//surface創(chuàng)建了

@Override

public void surfaceCreated(SurfaceHolder holder) {

System.out.println("創(chuàng)建了??");

int position = sp.getInt("position", 0);

mPlayer.setDisplay(sv.getHolder());????//顯示畫(huà)面,必須設(shè)置

mPlayer.start();

mPlayer.seekTo(position);??// 直接跳到某個(gè)位置, 從這個(gè)位置開(kāi)始播放

}

//surface變化了

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

System.out.println("修改了??");

}

});

#ScollView#??只能有一個(gè)子節(jié)點(diǎn)

#WebView#

webview = new WebView(this);

//設(shè)置WebView屬性,能夠執(zhí)行Javascript腳本

webview.getSettings().setJavaScriptEnabled(true);

//加載需要顯示的網(wǎng)頁(yè)

webview.setWebViewClient(new WebViewClient());

webview.loadUrl("http://www.xxxx.com/");

//設(shè)置Web視圖

setContentView(webview);

#Fragment#??碎片??類(lèi)似Activity

-1. 靜態(tài)添加碎片

1.自己布局一個(gè)fragment:

android:id="@+id/fm_left"????????//id必須寫(xiě),不然會(huì)報(bào)錯(cuò)

android:name="com.example.fragment.LeftFragment"http:// 添加name屬性,包名必須寫(xiě),此為加載LeftFragment 類(lèi)

android:layout_weight="1"

android:layout_width="0dp"

android:layout_height="match_parent"/>

2.定義一個(gè)LeftFragment 繼承 Fragment

public class LeftFragment extends Fragment {

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

//false 代表 不附著在parent布局中

return inflater.inflate(R.layout.left, container,false);

}

}

3.定義一個(gè)R.layout.left布局文件

-2. 動(dòng)態(tài)添加碎片

核心代碼



RightFragment rightFragment = new RightFragment();

FragmentManager fragmentManager = getFragmentManager();

FragmentTransaction beginTransaction = fragmentManager.beginTransaction();

beginTransaction.replace(R.id.fl, rightFragment);

beginTransaction.commit();

3. 四種對(duì)話框(不能用Application的上下文)

-1.取消對(duì)話框

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("please ");????????????// 下面都對(duì)話框都可以設(shè)置標(biāo)題

builder.setMessage("繼續(xù)擼代碼嗎?");????????// 同上

builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

Toast.makeText(MainActivity.this, "lu", 0).show();

}

});????????//確定按鈕的點(diǎn)擊事件

builder.setNegativeButton("No", null);????//取消按鈕的點(diǎn)擊事件

builder.show();

-2.單選對(duì)話框

Builder builder = new AlertDialog.Builder(this);

final String[] items = new String[]{"male","female"};

builder.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() {

@Override

//which 是數(shù)組的 索引,下同

public void onClick(DialogInterface dialog, int which) {

Toast.makeText(MainActivity.this, "你選的是"+items[which], 0).show();

}

});

builder.show();

-3.多選對(duì)話框

AlertDialog.Builder builder = new AlertDialog.Builder(this);

final String[] items = new String[]{"跳樓","上吊","擼代碼","滾回家"};

final boolean[] checkedItems = new boolean[]{false,false,false,false};

// fasle 代表默認(rèn)不被選中

builder.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {

@Override

public void onClick(DialogInterface dialog, int which, boolean isChecked) {

Toast.makeText(MainActivity.this, "你選的是"+items[which], 0).show();

checkedItems[which] = isChecked;

}

});

builder.show();

-4.進(jìn)度條對(duì)話框

final ProgressDialog progressDialog = ProgressDialog.show(MainActivity.this, "please wait", "加載loading。。。。。");

new Thread(){

public void run(){

progressDialog.setCancelable(false);//Back鍵不能取消掉

SystemClock.sleep(2000);

progressDialog.dismiss();????????????//設(shè)置 dismiss 退出

}

}.start();

***所有的控件都有的屬性:visibility{visible(默認(rèn),可見(jiàn)),invisible(不可見(jiàn)占空間),gone(不可見(jiàn)也不占空間)}

4. 自定義控件

開(kāi)源框架:SmartImageView(看源碼)---- SmartImageView.setImageUrl(Url url){}

1 . 繼承原生控件

2 . 重寫(xiě)構(gòu)造方法

3 . 根據(jù)業(yè)務(wù)需求定義方法

5. ListView

-1.作用和方法:用來(lái)將數(shù)據(jù)顯示到屏幕上的技術(shù)

google按照mvc的三層架構(gòu)思想設(shè)計(jì)

m:model--- 模型--- 需要顯示的數(shù)據(jù)

v:view ---視圖---- 呈現(xiàn)的界面

c:controller--- 控制器--- Adapter(適配器)

1. lv.setSelection(random1); //該方法可以 ListView 定位到讓指定位置(random1),就是讓指定位置的條目位于當(dāng)前界面第一行。非常準(zhǔn)確。

2. lv.smoothScrollToPosition(xxx); //該方法可以讓 ListView 平滑的滾動(dòng)到指定位置(xxx),但是非常不準(zhǔn)確。

3.??lv1.setOnScrollListener(OnScrollListener); //給ListView 設(shè)置監(jiān)聽(tīng)器

4. //滑動(dòng)時(shí)回調(diào)的方法

// scrollState 滾動(dòng)狀態(tài)有三種:0 靜止,1 手指滑動(dòng),2慣性滾動(dòng)

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) { }

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}

-2.BaseAdapter????---是ListAdapter的一個(gè)默認(rèn)實(shí)現(xiàn)類(lèi)

主要需要重寫(xiě)的2個(gè)方法:

public int getCount(){????????//總共需要顯示數(shù)據(jù)條數(shù)

return list.size();

}

public public View getView(int position, View convertView, ViewGroup parent) {

//三種填充View的方法,本質(zhì)是一樣的

//第一種

View view = View.inflate(MainActivity.this,R,layout.item_main,null);

//第二種

View view = LayoutInflater.from(MainMainActivity.this).inflate(R,layout.item_main,null);

//第三種

LayoutInflater ll = (LayoutInflater)getSystemService("LAYOUT_INFLATER_SERVICE");

View view = ll.inflate(R,layout.item_main,null);

}

-3.ArrayAdapter

listView.setAdapter(new ArrayAdapter(MainActivity.this,R.layout.item,T[] Objects));

最后一個(gè)參數(shù)也可以是集合。

-4.SimpleAdapter

待完善

-5.優(yōu)化

(1)//刪除之前已經(jīng)顯示的數(shù)據(jù) ,然后再次重新加載進(jìn)來(lái),這樣避免重復(fù)顯示

if(myadapter ==null){

myadapter = new MyAdapter();

lv.setAdapter(myadapter);

}else{

//要通知適配器去更新一下數(shù)據(jù)

myadapter.notifyDataSetChanged();

}

(2)防止OOM(Out Of Memory)異常

View view;

if(convertView==null){

view = View.inflate(MainActivity.this, R.layout.item, null);

}else{

view =convertView;

}

if(convertView==null){

convertView = View.inflate(MainActivity.this, R.layout.item, null);

}

(3)faster(用Holder)持有器

static class ViewHolder {

TextView tv;

ImageView iv;

View Holder holder;

if (convertView == null) {

convertView=View.inflate(MainActivity.this,R.layout.item,null);

holder = new ViewHolder();

holder.iv = (ImageView) convertView.findViewById(R.id.iv);

holder.tv_title = (TextView) convertView.findViewById(R.id.tv);

convertView.setTag(holder);

}else{

holder = (ViewHolder) convertView.getTag();

##3.數(shù)據(jù)存儲(chǔ)和解析

1. 文件存儲(chǔ)

-1.基本輸入輸出流文件

-2.Context提供了兩個(gè)方法來(lái)打開(kāi)數(shù)據(jù)文件里的文件IO流,存儲(chǔ)路徑:/data/data//files

openFileInput("xxx.txt"); //讀取

openFileOutput("xxx.txt",Context.MODE_PRIVATE);????//保存

//MODE_PRIVATE:為默認(rèn)操作模式,代表該文件是私有數(shù)據(jù),只能被應(yīng)用本身訪問(wèn),在該模式下,寫(xiě)入的內(nèi)容會(huì)覆蓋原文件的內(nèi)容

//MODE_APPEND:模式會(huì)檢查文件是否存在,存在就往文件追加內(nèi)容,否則就創(chuàng)建新文件;

//后面的兩種模式在Android4.2被廢棄,不安全

//MODE_WORLD_READABLE:表示當(dāng)前文件可以被其他應(yīng)用讀取;

//MODE_WORLD_WRITEABLE:表示當(dāng)前文件可以被其他應(yīng)用寫(xiě)入。

deleteFile("xxx.txt");????//刪除

File getFilesDir():獲取該應(yīng)用程序的數(shù)據(jù)文件夾得絕對(duì)路徑

File getCacheDir():緩存區(qū)

String[] fileList():返回該應(yīng)用數(shù)據(jù)文件夾的全部文件

-3.Sdcard 存儲(chǔ)

1、調(diào)用Environment的getExternalStorageState()方法判斷手機(jī)上是否插了sd卡,且應(yīng)用程序具有讀寫(xiě)SD卡的權(quán)限,如下代碼將返回true

Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)

2、調(diào)用Environment.getExternalStorageDirectory()方法來(lái)獲取外部存儲(chǔ)器,也就是SD卡的目錄,或者使用"/mnt/sdcard/"目錄

File file = new File(Environment.getExternalStorageDirectory(),filename);

3、使用IO流操作SD卡上的文件

注意點(diǎn):

手機(jī)應(yīng)該已插入SD卡,對(duì)于模擬器而言,可通過(guò)mksdcard命令來(lái)創(chuàng)建虛擬存儲(chǔ)卡

必須在AndroidManifest.xml上配置讀寫(xiě)SD卡的權(quán)限

2. SharedPreferences存儲(chǔ) --- 單例,一般不會(huì)發(fā)生并發(fā)沖突

1.創(chuàng)建文件:????SharedPreferences sp = context.getSharedPreferences("xxx",int mode);//創(chuàng)建的xxx一定是xml文件,存儲(chǔ)在/data/data//shared_prefs,參數(shù)mode 和上面一樣。

2.存儲(chǔ)數(shù)據(jù):????Editor edit = sp.edit();

edit.putXxx(String key,Xxx value);

edit.commit(); || edit.apply();

區(qū)別: 1. apply沒(méi)有返回值apply方法不會(huì)提示任何失敗的提示。而commit返回boolean表明修改是否提交成功

2. apply異步提交數(shù)據(jù),commit同步。

3.讀取數(shù)據(jù): sp.getXxx(String key,XxxDefault);// 如果沒(méi)有讀取到,就返回第二參數(shù)。

4.刪除數(shù)據(jù): sp.remove(String key);//刪除key字段

sp.clear();//清空文件

3. SQLite數(shù)據(jù)庫(kù)存儲(chǔ)

-1.創(chuàng)建表

db.execSQL("create table tablename(_id integer primary key autoincrement,name varchar(30),age Integer)");

-2.Insert

第一種:存在sql注入問(wèn)題

db.execSQL("insert into tablename(name,age) values('Myth',2)");

第二種:通過(guò)占位符? 解決sql注入

db.execSQL("insert into tablename(name,age) values(?,?)",new Object[]{"Myth",2});

第三種:底層還是通過(guò)拼接字符串得到sql語(yǔ)句

ContentValues values = new ContentValues();

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

values.put("age",2);

db.insert("tablename",columnNull,values);//第二個(gè)參數(shù):sql表不允許插入空,所以就會(huì)用null當(dāng)作該值插入表。

-3.Delete

db.execSQL("delete from tablename where _id = 2");

db.execSQL("delete from tablename where _id = ?",new Object[]{2});

db.delete("tablename","_id = ?",new String[]{String.valueOf(id)});

-4.Update

db.execSQL("update tablename set name = 'Myth' where age = 2");

db.execSQL("update tablename set name=?,age =? where _id=?",new Objecet[]{"Myth",2,2});

ContentValues values = new ContentValues();

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

values.put("age",2);

db.update("tablename",values,"_id=?",new String[]{String.valueOf(id)});

-5.Query

Cursor cursor = db.rawQuery("select * from tablename where _id=2");

Cursor cursor = db.rawQuery("select * from tablename where _id=?",new Object[]{2});

Cursor cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);

if(cursor.moveToFirst){

while(cursor.moveToNext){

}

}

4. SQLite實(shí)踐

-1.事務(wù)操作??--- 同時(shí)處理多條數(shù)據(jù)時(shí),保證數(shù)據(jù)安全性

db.beginTransaction();

try {

db.setTransactionSuccessful();//執(zhí)行提交

} finally {

db.endTransaction();

}

-2.數(shù)據(jù)庫(kù)升級(jí)操作 --- 保證版本更新成功

switch (oldVersion) {

case 1:????????//代表每個(gè)版本的操作 該case 是1~2的升級(jí)操作

case 2:????????//case 一直到最新版本

default:

}

-3.注意:getWritableDatabase()和getReadableDatabase()方法的區(qū)別:

getWriteableDatabase()方法以讀寫(xiě)方式打開(kāi)數(shù)據(jù)庫(kù)一旦數(shù)據(jù)庫(kù)的磁盤(pán)空間滿了,數(shù)據(jù)庫(kù)就只能讀而不能寫(xiě),倘若使用getWritableDatabase()打開(kāi)數(shù)據(jù)庫(kù)就會(huì)出錯(cuò)。

getReadableDatabase()方法先以讀寫(xiě)方式打開(kāi)數(shù)據(jù)庫(kù),如果數(shù)據(jù)庫(kù)的磁盤(pán)空間滿了,就會(huì)打開(kāi)失敗,當(dāng)打開(kāi)失敗后會(huì)繼續(xù)嘗試以只讀的方式打開(kāi)數(shù)據(jù)庫(kù).

5. XML生成器:XmlSerializer和 XML解析器:XmlPullParser

-1.XmlSerializer:(字符串拼接X(jué)m文件存在語(yǔ)句注入問(wèn)題,so用XmlSerializer)

XmlSerializer serializer = Xml.newSerializer();

serializer.setOutput(fos,"UTF-8");

serializer.startDocument("UTF-8",true);// "

serializer.startTag(null, "smses");

for (int i = 0; i < 50; i++) {

serializer.startTag(null, "sms"); //第一個(gè)參數(shù)為命名空間

serializer.startTag(null, "body");

serializer.text("我是內(nèi)容<>" + i);

serializer.endTag(null, "body");

serializer.endTag(null, "sms");

}

serializer.endTag(null, "smses");

serializer.endDocument;

fos.close;

-2.XmlPullParser:

XmlPullParser pullparser = Xml.newPullParser();

pullparser.setInput(fis,"UTF-8");

int eventType = pullparser.next();

while(eventType != XmlPullParser.END_DOCUMENT){

switch(eventType){

case XmlPullParser.START_TAG:

if ("smses".equals(tagName)) {

list = new ArrayList();

}else if ("sms".equals(tagName)) {

sms = new Sms();

}else if ("body".equals(tagName)) {

sms.setBody(parser.nextText());

}

break;

case XmlPullParser.END_TAG:

if ("sms".equals(tagName)) {

list.add(sms);

}

break;

}

eventType = pullparser.next();

}

##4.Activity

-1.自定義的Activity

-1.創(chuàng)建一個(gè)MyActivtiy實(shí)現(xiàn)Activity

public class MyActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

}

-2.新建一個(gè)布局文件 xxx.xml

-3.在onCreate()方法里寫(xiě) 上 setContentView(R.layout.xxx);

-4.最重要的一步:在清單文件中注冊(cè)一個(gè)自己的Activity

android:name="com.example.MyActivity"????//可以縮寫(xiě).MyActivity

android:label="@string/app_name" >????????//標(biāo)題欄的內(nèi)容

-5.非必須的一步:隱藏標(biāo)題欄 ---在onCreate()方法內(nèi)寫(xiě)

requestWindowFeature(Window.FEATURE_NO_TITLE);

-2.生命周期

OnCreate()????????創(chuàng)建界面

OnStart()????????不可見(jiàn)---->可見(jiàn)??時(shí)候會(huì)調(diào)用

OnResume()????????獲得焦點(diǎn),此時(shí)活動(dòng)在棧頂,處于運(yùn)行狀態(tài)

OnPause()????????失去焦點(diǎn),不在棧頂?shù)梢?jiàn),處于暫停狀態(tài)

OnStop()????????可見(jiàn)---->不可見(jiàn)??時(shí)候會(huì)調(diào)用,處于停止?fàn)顟B(tài)

OnDestroy()????????銷(xiāo)毀

**注意:要使得Activity不可見(jiàn),可以再建一個(gè)項(xiàng)目同時(shí)運(yùn)行,將其Application的theme屬性改成透明狀態(tài):

android:theme="@android:style/Theme.Translucent">

-3.活動(dòng)的四種啟動(dòng)模式(android:launchMode="")

-1.standard:每次啟動(dòng)acitvity組件時(shí), 都會(huì)新創(chuàng)建activity 實(shí)例,是活動(dòng)默認(rèn)的啟動(dòng)模式

-2.singleTop:如果某個(gè)activity設(shè)置單一頂部模式, 那么當(dāng)發(fā)現(xiàn)當(dāng)前的activity就在當(dāng)前任務(wù)棧的頂部, 那么就不再新創(chuàng)建當(dāng)前的activity的實(shí)例.例如:系統(tǒng)的短信

-3.singleTask:如果當(dāng)前任務(wù)棧中已經(jīng)有當(dāng)前activity 的實(shí)例, 那么就將當(dāng)前activity 的實(shí)例直接拿過(guò)來(lái)用, 用的時(shí)候,如果當(dāng)前activity 不在棧頂,那么將在當(dāng)前activity 之上的其他的activity的實(shí)例 給干掉... 然后再處于棧頂了一般情況下, 當(dāng)某個(gè)activity??啟動(dòng)的時(shí)候, 要占用的內(nèi)存比較大, 而手機(jī)上的內(nèi)存又是有限的, 那么這個(gè)時(shí)候, 就推薦將這個(gè)activity的啟動(dòng)模式設(shè)置為單一任務(wù)棧模式.例如:系統(tǒng)的瀏覽器

-4.singleInstance:如果某個(gè)activity 的啟動(dòng)模式設(shè)置為單一實(shí)例模式, 那么系統(tǒng)會(huì)為這個(gè)activity 單獨(dú)的去開(kāi)辟一個(gè)任務(wù)棧,這個(gè)任務(wù)棧中,只放這個(gè) activity的實(shí)例.這樣確保了整個(gè)操作系統(tǒng)中,只有一個(gè)這個(gè)activity的實(shí)例了.如果某個(gè)activity在整個(gè)系統(tǒng)中就只需要有一個(gè)實(shí)例, 并且永遠(yuǎn)不會(huì)更改, 那么就推薦使用這種模式.例如:系統(tǒng)的電話

-4.使用intent在活動(dòng)之間傳輸數(shù)據(jù)

-1.顯示意圖:是明顯的指定要激活哪個(gè)組件 ..一般建議用在應(yīng)用程序內(nèi)部 .

Intent intent = new Intent();

//????intent.setClass(this, SecondActivity.class);

//????intent.setClassName("com.itheima.exactintent", "com.itheima.exactintent.SecondActivity");

intent.setClassName(this,??"com.itheima.exactintent.SecondActivity");

startActivity(intent);

-2.隱式意圖:是指不明確到底哪個(gè)組件可以響應(yīng)你的意圖,你只需要將意圖發(fā)出去就可以了.當(dāng)存在滿足你的意圖的組件時(shí),

這個(gè)時(shí)候,系統(tǒng)就會(huì)將組件給激活起來(lái)...一般用在不同應(yīng)用程序之間 激活組件 ..

Intent intent = new Intent();

//必須和Activity下的intent-filter內(nèi)容匹配

intent.setAction("com.itheima.nu");

//????intent.addCategory("android.intent.category.DEFAULT");

intent.addCategory(Intent.CATEGORY_DEFAULT);

startActivity(intent);

****1. 每個(gè)應(yīng)用中的組件是可以配置多個(gè)Intent-filter,可以配置多個(gè)隱式意圖去激活這個(gè)組件

2. 如果想要激活這個(gè)組件, 只需要發(fā)送對(duì)應(yīng)的隱式意圖就可以了.

-3.intent中setData:接收一個(gè)Uri對(duì)象,例如:intent.setData(Uri.parse("www.baidu.com"));

與其對(duì)應(yīng),可以在標(biāo)簽中配置一個(gè)子標(biāo)簽。

屬性:scheme(http),host(www.baidu.com),port(8080),path(指定端口號(hào)后面的部分),mimeType(指定可以處理的數(shù)據(jù)類(lèi)型,允許使用通配符)

-4.intent攜帶數(shù)據(jù),實(shí)現(xiàn)短信分享:

Intent intent = new Intent();

//短信有很多intent-filter,只需要其中匹配上一個(gè)即可

intent.setAction("android.intent.action.SENDTO");

intent.addCategory("android.intent.category.DEFAULT");

intent.addCategory("android.intent.category.BROWSABLE");

intent.setData(Uri.parse("smsto://xxxxx"));

intent.putExtra("sms_body", "xxxxxxxxxx");

startActivity(intent);

//Activity接收數(shù)據(jù)

Intent intent = getIntent();

String data = intent.getExtraString("sms_body");

-5.帶有返回結(jié)果的intent

主Activity:

Intent intent2 = new Intent();

intent2.setClass(this, xxx.class);

startActivityForResult(intent2, 2);

//接收其他Activity回傳的結(jié)果數(shù)據(jù)

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

System.out.println("結(jié)果返回到這里了 ....");

if(requestCode==1){

}else if(requestCode==2){

}

super.onActivityResult(requestCode, resultCode, data);

}

xxxActivity:

Intent data = new Intent();

data.putExtra("contact", contact);

setResult(0, data);

finish();????????// 關(guān)閉該xxxActivity

-6.其他

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);重新啟動(dòng)Activity

intent.addAction("android.media.action.IMAGE_CAPTURE");啟動(dòng)相機(jī)

##5.BroadcastReceiver(買(mǎi)收音機(jī),裝電池,調(diào)頻道)

-1.動(dòng)態(tài)注冊(cè)廣播接收者

(1)監(jiān)聽(tīng)手機(jī)屏幕開(kāi)關(guān)

receiver = new ScreenStateReceiver();//繼承BroadcastReceiver

IntentFilter filter = new IntentFilter();

filter.addAction("android.intent.action.SCREEN_OFF");

filter.addAction("android.intent.action.SCREEN_ON");

registerReceiver(receiver, filter);//注冊(cè) 廣播接收者

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if("android.intent.action.SCREEN_OFF.equals(action)){

System.out.println("發(fā)現(xiàn)用戶(hù)屏幕關(guān)了??");

abortBroadcast();//攔截廣播

}else if("android.intent.action.SCREEN_ON".equals(action)){

System.out.println("發(fā)現(xiàn)用戶(hù)屏幕開(kāi)啟 ");

}

}

(2)監(jiān)聽(tīng)網(wǎng)絡(luò)變化

receiver = new NetworkChangeReceiver();//繼承BroadcastReceiver

IntentFilter filter = new IntentFilter();

filter.addAction("android.intent.action.CONNECTIVITY_CHANGE");

registerReceiver(receiver, filter);//注冊(cè) 廣播接收者

(3)需要手動(dòng)取消注冊(cè)

在onDestroy()中調(diào)用 unregisterReceiver(receiver);

-2.靜態(tài)注冊(cè)一個(gè)廣播接收者 --- 監(jiān)聽(tīng)開(kāi)機(jī)啟動(dòng)

//優(yōu)先級(jí)-1000~10000,優(yōu)先接收廣播

-3.發(fā)送無(wú)序廣播

// 定義 intent , intent 設(shè)置 必要的信息就可以 了

Intent intent = new Intent();

intent.setAction("com.example.xxx");

// 發(fā)送 廣播

sendBroadcast(intent);

-4.發(fā)送有序廣播

// 定義 intent , intent 設(shè)置 必要的信息就可以 了

Intent intent = new Intent();

intent.setAction("com.example.xxx");

// 發(fā)送 廣播

sendOrderBroadcast(intent,null);//第二個(gè)參數(shù)是一個(gè)與權(quán)限有關(guān)的字符串

##6.Server

-1.Handler異步消息處理機(jī)制(IPC 線程通信,避免發(fā)生ANR 問(wèn)題,在Activity中 耗時(shí)操作 5s 產(chǎn)生ANR。)

-1.Message:線程間傳遞消息,

//獲得消息對(duì)象,兩種方式本質(zhì)一樣

Message msg = handler.obtainMessage();

Message msg = Message.obtain();

msg.sendToTarget(); //該msg需要綁定handler,從handler.obtainMessage()獲取

-2.Handler:用于發(fā)送和處理消息

handler.sendMessage();

handler.sendEmptyMessage();//發(fā)送無(wú)效消息

private Handler handler = new Handler(){

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case SUCCESS:

Xxx data = (Xxx)msg.obj;

Toast.makeText(MainActivity.this, "成功", 0).show();

break;

case FAILURE:

Toast.makeText(MainActivity.this, "失敗", 0).show();

break;

}

}

};

-3.MessageQueue :消息隊(duì)列,存放將要被處理的消息,每個(gè)線程只有一個(gè)MessageQueue

-4.Looper:調(diào)用loop(),進(jìn)入一個(gè)無(wú)線循環(huán)中,不斷取出MessageQueue中的消息傳遞到handleMessage()中,每個(gè)線程也只有一個(gè)Looper對(duì)象。

-5.發(fā)送消息代碼

Message msg = Message.obtain();

msg.what = SUCCESS;????????// what 區(qū)分發(fā)送的消息類(lèi)型

msg.obj = data;????????????// obj 攜帶任意消息

handler.sendMessage(msg);

-2.AsyncTask ---Android已經(jīng)封裝好,方便在子線程中對(duì)UI進(jìn)行操作。(待更新)

-3.進(jìn)程優(yōu)先級(jí)分類(lèi):

-1.前臺(tái)進(jìn)程: 就是正在與用戶(hù)進(jìn)程交互的引用程序

-2.可視進(jìn)程: 用戶(hù)看得見(jiàn)的,但是摸不著的

-3.服務(wù)進(jìn)程: 在服務(wù)中運(yùn)行, 在后臺(tái)運(yùn)行著

-4.后臺(tái)進(jìn)程: 在后臺(tái)一直運(yùn)行著,不是運(yùn)行在service ,是運(yùn)行在activity中

-5.空進(jìn)程:??引用程序已經(jīng)退出了,沒(méi)有activity,沒(méi)有service .

-6.總結(jié):前臺(tái)進(jìn)程> 可視進(jìn)程> 服務(wù)進(jìn)程> 后臺(tái)進(jìn)程> 空進(jìn)程???當(dāng)系統(tǒng)內(nèi)存不夠用的時(shí)候, 就會(huì)去嘗試回收進(jìn)程,來(lái)重新分配內(nèi)存. 會(huì)按照如上優(yōu)先級(jí)分類(lèi)殺掉進(jìn)程.

-4.自定義服務(wù)

public class MyService extends Service {

@Override

public IBinder onBind(Intent intent) {

return new MyBinder();

}

}

// 必須清單文件注冊(cè)

-5.開(kāi)啟服務(wù)的生命周期

onCreate()????????????//服務(wù)創(chuàng)建時(shí)調(diào)用

onStartComment()????//每次服務(wù)啟動(dòng)時(shí)調(diào)用,廢棄了onStart()

onDestroy()????????????//服務(wù)銷(xiāo)毀時(shí)調(diào)用

-1.開(kāi)啟服務(wù)

Intent intent = new Intent();

intent.setClass(MainActivity.this,MyService.class);

startService(intent);

-2.停止服務(wù)

Intent intent = new Intent();

intent.setClass(MainActivity.this,MyService.class);

stopService(intent);

-6.綁定服務(wù)的生命周期

onCreate()????????//創(chuàng)建服務(wù)

onBind()?????????//綁定服務(wù)

onUnbind()?????????//解除綁定服務(wù)

onDestroy()?????//銷(xiāo)毀服務(wù)

(1)綁定服務(wù)時(shí), onStartCommand并不會(huì)執(zhí)行,

(2)綁定服務(wù),服務(wù)何時(shí)銷(xiāo)毀呢, 在應(yīng)用程序退出的時(shí)候就銷(xiāo)毀了

(3)綁定服務(wù), 服務(wù)不會(huì)在后臺(tái)運(yùn)行 ---在apps中running 中是看不到的

(4)開(kāi)啟服務(wù), 服務(wù)會(huì)在后臺(tái)運(yùn)行--- 可以在apps中 runnning 中看到

(5)綁定服務(wù), 服務(wù)只會(huì)創(chuàng)建一次, 如果再次綁定服務(wù), 那么服務(wù)是不會(huì)重新再次創(chuàng)建的.

(6)如果沒(méi)有綁定服務(wù), 就直接去解綁服務(wù), 那么會(huì)拋異常.so 需要做如下判斷,避免異常

if(conn != null){

unbindService(conn);

conn = null;

mybinder = null;

}

-7.綁定服務(wù)實(shí)現(xiàn)流程(活動(dòng)和服務(wù)間通信,進(jìn)程間通信使用 IBinder)

-1.綁定服務(wù)

Intent intent = new Intent();

intent.setClass(this, MyService.class);

if(conn == null){

conn = new MyConnection();

}

bindService(intent, new MyConnection(), BIND_AUTO_CREATE);

-2.編寫(xiě)MyBinder 繼承 Binder 實(shí)現(xiàn) IService??// IService 接口中是將要調(diào)用的方法

private class MyBinder extends Binder implements IService{

@Override

// 服務(wù)中對(duì)外提供的方法封裝在接口中,重寫(xiě)接口中的方法

public void call(String name, String service) {

calle(name, service);

}

//該方法為不對(duì)外提供的方法,只對(duì)內(nèi)訪問(wèn)

public void callee(String name, String service) {

System.out.println("呼叫前臺(tái)");

}

}

-3.向Activity傳回MyBinder對(duì)象

@Override

public IBinder onBind(Intent intent) {

return new MyBinder();

}

-4.實(shí)現(xiàn)MyConnection 實(shí)現(xiàn) ServiceConnection接口

private class MyConnection implements ServiceConnection{

@Override

//當(dāng)與服務(wù)建立聯(lián)系的時(shí)候被回調(diào)

public void onServiceConnected(ComponentName name, IBinder service) {

if(mybinder == null){

mybinder = (IService) service;

//????mybinder = IService.Stub.asInterface(service);

}

}

@Override

//當(dāng)與服務(wù)斷開(kāi)聯(lián)系的時(shí)候被回調(diào)

public void onServiceDisconnected(ComponentName name) {

mybinder = null;

}

}

-5.調(diào)用服務(wù)中的方法

mybinder.call("xxxx", "xxxx");

-8.不同Activity之間通信

主要編寫(xiě).aidl

(1)語(yǔ)法與接口很類(lèi)似,直接修改接口文件后綴名即可。但是.aidl文件中不能寫(xiě)權(quán)限修飾符

(2).aidl文件接受參數(shù)和返回值類(lèi)型是8種基本數(shù)據(jù)類(lèi)型,如果是引用數(shù)據(jù)類(lèi)型,必須實(shí)現(xiàn)Parceable接口

(3)不能修改.aidl文件生成的.java類(lèi)

-1 Parceable 比 Serializable 性能高

-2 Serializable 使用時(shí)會(huì)產(chǎn)生大量臨時(shí)變量,引起頻繁的GC

-3 Parceable 不能保證數(shù)據(jù)的持續(xù)性,不能使用數(shù)據(jù)保存在磁盤(pán)上

-9.混合開(kāi)發(fā)服務(wù)

(1)開(kāi)啟服務(wù):只能在后臺(tái)運(yùn)行

(2)綁定服務(wù):只能調(diào)用服務(wù)中的方法

想在后臺(tái)運(yùn)行,但是同時(shí)又想 調(diào)用服務(wù)中 方法, 那么 就需要混合開(kāi)啟服務(wù)了.

以后,如果需要在后臺(tái)運(yùn)行, 并且又需要調(diào)用服務(wù)中的方法時(shí),請(qǐng)嚴(yán)格按照 如下的順序去 實(shí)現(xiàn)程序的邏輯, 否則 就容易出現(xiàn)問(wèn)題..

混合開(kāi)啟:

開(kāi)啟服務(wù)

綁定服務(wù)

調(diào)用服務(wù)中的方法

解除綁定

停止服務(wù)

例如:QQ 在退出的時(shí)候,選擇退出后, 仍然可以接受消息, 就可以使用混合開(kāi)啟服務(wù)的方式...

-10.Android提供一個(gè)IntentService類(lèi):是一個(gè)異步的,會(huì)自動(dòng)停止的服務(wù),可以避免ANR問(wèn)題(服務(wù)在主線程中耗時(shí)操作 10s 產(chǎn)生ANR 問(wèn)題)

public class MyIntentService extends IntentService {

public MyIntentService() {

super("MyIntentService");

}

@Override

protected void onHandleIntent(Intent intent) {

}????????//處理具體的邏輯

}

// 清單文件注冊(cè)

##7.ContentProvider

-1.自定義內(nèi)容提供者??---ContentProvider

public class MyContentProvider extends ContentProvider {

private static final int SUCCESS = 0;

private static UriMatcher matcher;

//匹配器 -- UriMatcher

//是固定的寫(xiě)法

//這里的no_match是用來(lái)指定當(dāng)匹配不成功時(shí),返回的值

static {

matcher = new UriMatcher(UriMatcher.NO_MATCH);

// com.itheima.xxx 公開(kāi)的名稱(chēng), table就是暗號(hào)了, SUCCESS指匹配成功后返回的結(jié)果

matcher.addURI("com.example.xxx", "table", SUCCESS);

}

@Override

public boolean onCreate() {

return false;

}

@Override

public Cursor query(Uri uri, String[] projection, String selection,

String[] selectionArgs, String sortOrder) {

BankOpenHelper myOpenHelper = new MyOpenHelper(getContext());

SQLiteDatabase db = myOpenHelper.getWritableDatabase();

if (matcher.match(uri) == SUCCESS) {

return db.query("table", projection, selection, selectionArgs, null,

null, sortOrder);

}

return null;

}

@Override

public String getType(Uri uri) {

return null;

}

@Override

public Uri insert(Uri uri, ContentValues values) {

BankOpenHelper myOpenHelper = new MyOpenHelper(getContext());

SQLiteDatabase db = myOpenHelper.getWritableDatabase();

// TODO Auto-generated method stub

if (matcher.match(uri) == SUCCESS) {

db.insert("table", null, values);

} else {

try {

throw new Exception("暗號(hào)錯(cuò)誤。");

} catch (Exception e) {

e.printStackTrace();

}

}

return null;

}

@Override

public int delete(Uri uri, String selection, String[] selectionArgs) {

BankOpenHelper myOpenHelper = new MyOpenHelper(getContext());

SQLiteDatabase db = myOpenHelper.getWritableDatabase();

if (matcher.match(uri) == SUCCESS) {

return db.delete("account", selection, selectionArgs);

}

return 0;

}

@Override

public int update(Uri uri, ContentValues values, String selection,

String[] selectionArgs) {

BankOpenHelper myOpenHelper = new MyOpenHelper(getContext());

SQLiteDatabase db = myOpenHelper.getWritableDatabase();

if (matcher.match(uri) == SUCCESS) {

return db.update("account", values, selection, selectionArgs);

}

return 0;

}

}

##清單文件注冊(cè):

-2. 內(nèi)容解析者 ---- ContentResolver (類(lèi)似SQLite操作)

1 insert

ContentResolver resolver = getContentResolver();

Uri url = Uri.parse("content://com.example.xxx/table");

ContentValues values = new ContentValues();

values.put("key", "value");

resolver.insert(url, values);

2.delete

ContentResolver resolver = getContentResolver();

Uri url = Uri.parse("content://com.example.xxx/table");

resolver.delete(url, "key=?", new String[]{"value"});

3.update

ContentResolver resolver = getContentResolver();

Uri url = Uri.parse("content://com.example.xxx/table");

ContentValues values = new ContentValues();

values.put("key1", "value1");

resolver.update(url, values, "key=?", new String[]{"value"});

4.query

ContentResolver resolver = getContentResolver();

Uri url = Uri.parse("content://com.example.xxx/table");

Cursor cursor = resolver.query(url, null, "key=?", new String[]{"value"}, null);

while(cursor.moveToNext()){

}

-3.內(nèi)容觀察者 --- ContentObserver

(1)ContentResolver resolver = getContentResolver();

//注冊(cè)一個(gè)內(nèi)容觀察者

//如果notifyForDescendents參數(shù)設(shè)為true,假如Uri為content://abc,那么Uri為content://abc/xyz, content://abc/xyz/foo的數(shù)據(jù)改變時(shí)也會(huì)觸發(fā)該監(jiān)聽(tīng)器,如果參數(shù)為false,那么只有content://abc的數(shù)據(jù)改變時(shí)會(huì)觸發(fā)該監(jiān)聽(tīng)器

resolver.registerContentObserver(uri, boolean notifyForDescendents, new ContentObserver(null) {

// selfChange : 數(shù)據(jù)的變化是否是來(lái)自于自己

@Override

public void onChange(boolean selfChange) {

System.out.println("數(shù)據(jù)發(fā)生變化了 ....");

}

});

(2)在不需要時(shí),需要手動(dòng)的調(diào)用

unregisterContentObserver()去取消注冊(cè)。

(3)ContentObserver類(lèi)介紹

構(gòu)造方法 public void ContentObserver(Handler handler) {}

說(shuō)明:所有 ContentObserver的派生類(lèi)都需要調(diào)用該構(gòu)造方法

參數(shù): handler  Handler對(duì)象??梢允侵骶€程Handler(這時(shí)候可以更新UI了),也可以是任何Handler對(duì)象。

##8.手機(jī)多媒體

-1.通知的使用(NotificationManager)

-1.第一種

//拿到通知管理器

NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

Notification nf = new Notification(R.drawable.ic_launcher,"This is ticker Text ",System.currentTimeMillis());

// 第四個(gè)參數(shù)為延期意圖(能跳轉(zhuǎn)干你想干的事)

nf.setLatestEventInfo(context, "This is content title", "This is content text", null);

//顯示通知,第一個(gè)參數(shù)是每一個(gè)通知的id(保證不同)

nm.notify(1,nf);

-2.第二種

//基于Notification是builer模式構(gòu)建,可以鏈?zhǔn)骄幊虅?chuàng)建

Notification nf = new Notification.Builder(this)

.setContentTitle("你有消息")????????????//標(biāo)題

.setContentText("你mama 喊你回家吃飯")????//文本

.setSmallIcon(R.drawable.ic_launcher)????//小圖標(biāo)

.setLargeIcon(BitmapFactory.decodeResource(getResources(),

R.drawable.ic_launcher))?????//大圖標(biāo)

.build();

NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

nm.notify(1,nf);

-3.通過(guò)pending(延期意圖)撥打電話

Notification nf = new Notification(R.drawable.ic_launcher, "你好一有消息", System.currentTimeMillis());

Intent intent = new Intent();

intent.setAction(Intent.ACTION_CALL);

intent.setData(Uri.parse("tel:"+5556));

// pendingIntent 可以getActivity()??getService()??getBroadcast()

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

nf.setLatestEventInfo(this, "ai", "huijiachifan", pendingIntent);

//權(quán)限不能少,打電話權(quán)限

-2.短信的接收和發(fā)送(SmsManger)

-1.接收短信:監(jiān)聽(tīng) android.provider.Telephony.SMS_RECEIVED的廣播

public class MessageReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Bundle bundle = intent.getExtras();

//通過(guò)密鑰"pdus"獲取SMS pdu 數(shù)組,每一個(gè)pdu是一條短信

Object[] objects = (Object[])bundle.get("pdus");

for (Object object : objects) {

//將每一個(gè)pdu字節(jié)數(shù)組轉(zhuǎn)換SmsMessage對(duì)象

SmsMessage smsMessage = SmsMessage.createFromPdu((byte[])object);

//獲取短信的發(fā)送方號(hào)碼

if(smsMessage.getOriginatingAddress().equals("55666")){

//獲取短信

smsMessage.getMessageBody();

}

}

}

}

//接收短信權(quán)限

-2.發(fā)送短信

SmsManager smsManager = SmsManager.getDefault();

//發(fā)送很長(zhǎng)很長(zhǎng)的短信需要切割短信存到集合中,才能一條一次性發(fā)出去

ArrayList divideMessage = smsManager.divideMessage("");

smsManager.sendMultipartTextMessage("phone", null, divideMessage, null, null);

//接收短信權(quán)限

-3.監(jiān)聽(tīng)手機(jī)狀態(tài)(TelephonyManager):開(kāi)啟錄音功能(MediaRecoder)

TelephonyManager manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

manager.listen(new myPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);

private class myPhoneStateListener extends PhoneStateListener{

@Override

public void onCallStateChanged(int state, String incomingNumber) {

// TODO Auto-generated method stub

super.onCallStateChanged(state, incomingNumber);

switch (state) {

if(mRecorder != null){

stopRecording();

}

break;

case TelephonyManager.CALL_STATE_OFFHOOK:

startRecording();

break;

case TelephonyManager.CALL_STATE_RINGING:

break;

default:

break;

}

}

}

MediaRecorder mRecorder;

private void startRecording() {

//下面是模版,可以錄音文件的格式有:3gp,mp3。。。

mRecorder = new MediaRecorder();

mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

mRecorder.setOutputFile("/mnt/sdcard/jianting.3gp");

mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

try {

mRecorder.prepare();

} catch (IOException e) {

//????Log.e(LOG_TAG, "prepare() failed");

}

mRecorder.start();

}

private void stopRecording() {

mRecorder.stop();

mRecorder.release();

mRecorder = null;

}

//錄音權(quán)限,讀手機(jī)狀態(tài)權(quán)限

-4 播放音視頻(MediaPlayer)

setDataSource() // 設(shè)置要播放

seekTo()//????從指定位置播放

isPlaying()//當(dāng)前是否播放

getDuration// 獲取音頻時(shí)長(zhǎng)

// 開(kāi)始播放Button

public void start(View v){

//播放的地址

String dizhi = et_shu.getText().toString().trim();

if(TextUtils.isEmpty(dizhi)){

Toast.makeText(this, "不能為空", Toast.LENGTH_SHORT).show();

return;

}

player = new MediaPlayer();

player.reset();

try {

player.setDataSource(dizhi);

player.prepare();

//異步準(zhǔn)備

/*player.prepareAsync();

player.setOnPreparedListener(new OnPreparedListener() {

@Override

public void onPrepared(MediaPlayer mp) {

// TODO Auto-generated method stub

player.start();

}

});*/

player.start();

} catch (Exception e) {

e.printStackTrace();

}

}

// 暫停Button

public void pause(View v){

if(player!= null && player.isPlaying()){

player.pause();

return;

}

if(player!= null){

player.start();

}

}

// 停止Button

public void stop(View v){

if(player!= null){

player.stop();

player.release();

player = null;

}

}

-5.傳感器的使用(SensorManager)

SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

// Sensor.TYPE_XXX 可以獲取

Sensor lightSensor = sm.getDefaultSensor(Sensor.TYPE_XXX);

MySensorEventListener myListenser = new MySensorEventListener();

// 必須注冊(cè)監(jiān)聽(tīng)事件,第二個(gè)參數(shù) 是Senor實(shí)例,第三個(gè)參數(shù)是 傳感器輸出信息的更新速率

有4個(gè)值:SENSOR_DELAY_UI??SENSOR_DELAY_NORMAL??SENSOR_DELAY_GAME??SENSOR_DELAY_FASTEST???越來(lái)越快,耗電

sm.registerListener(myListenser, XXXSensor, SensorManager.SENSOR_DELAY_NORMAL);

}

// 不使用的時(shí)候取消監(jiān)聽(tīng),省電

@Override

protected void onDestroy() {

super.onDestroy();

if(myListenser!=null){

sm.unregisterListener(myListenser);

}

}

private class MySensorEventListener implements SensorEventListener{

// sensor獲得周?chē)h(huán)境數(shù)據(jù)發(fā)生變化時(shí) ,會(huì)被調(diào)用

@Override

public void onSensorChanged(SensorEvent event) {

//編寫(xiě)邏輯事件

}

// sensor獲得周?chē)h(huán)境數(shù)據(jù)發(fā)生變化時(shí),精確度發(fā)生變化時(shí)會(huì)被調(diào)用

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

}

// 獲取Sensor.TYPE_ALL

List list = sm.getSensorList(Sensor.TYPE_ALL);

System.out.println("數(shù)量 : " + list.size());

for (Sensor sensor : list) {

System.out.println(sensor.getName() +" , 類(lèi)型 值 : " + sensor.getType());

}

##9.網(wǎng)絡(luò)編程

-1.HttpURLConnection

1.get請(qǐng)求(拼接URL。。)

//防止亂碼??URL編碼

String username = URLEncoder.encode(username, "UTF-8");

String password = URLEncoder.encode(password, "UTF-8");

URL url = new URL(path+"?username="+username+"&password="+password);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");

//偽裝設(shè)置成windows端查看網(wǎng)頁(yè)

//conn.setRequestProperty("User-Agent",

"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586");

//設(shè)置連接超時(shí)時(shí)間

conn.setConnectTimeout(5000);

//獲取響應(yīng)碼

int code = conn.getResponseCode();

2.post請(qǐng)求

URL url = new URL(path);

String params = "?username="+URLEncoder.encode(username, "UTF-8")+"&password="+URLEncoder.encode(password, "UTF-8");

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("POST");

//設(shè)置連接超時(shí)時(shí)間

conn.setConnectTimeout(5000);

//獲取響應(yīng)碼

conn.setDoOutput(true);

conn.getOutputStream().write(params.getBytes());

int code = conn.getResponseCode();

-2.HttpClient(Apache) ---android 6.0 廢棄

1.get請(qǐng)求

username = URLEncoder.encode(username, "UTF-8");

String path = "http://169.254.26.249:8080/qqlogin/servlet/login?username="+username+"&password="+password;

DefaultHttpClient client = new DefaultHttpClient();

HttpGet get = new HttpGet(path);

//執(zhí)行請(qǐng)求,拿到響應(yīng)對(duì)象

HttpResponse response = client.execute(get);

int code = response.getStatusLine().getStatusCode();

if(code == 200){

//拿到服務(wù)端響應(yīng)的輸入流

InputStream is = response.getEntity().getContent();

String login = StreamTool.decodeStream(is);

2.post請(qǐng)求

String path = "http://169.254.26.249:8080/qqlogin/servlet/login";

DefaultHttpClient client = new DefaultHttpClient();

HttpPost post = new HttpPost(path);

//通過(guò)一個(gè)NameValuePair集合來(lái)存放待提交的數(shù)據(jù)

List list = new ArrayList();

list.add(new BasicNameValuePair("username", username));

list.add(new BasicNameValuePair("password", password));

//防止亂碼

post.setEntity(new UrlEncodedFormEntity(list , "UTF-8"));

//執(zhí)行請(qǐng)求,拿到響應(yīng)對(duì)象

HttpResponse response = client.execute(post);

int code = response.getStatusLine().getStatusCode();

if(code == 200){

InputStream is = response.getEntity().getContent();

String login = StreamTool.decodeStream(is);

-3.AsyncHttpClient---post請(qǐng)求

AsyncHttpClient client = new AsyncHttpClient();

RequestParams params = new RequestParams();

params.add("username", username);

params.add("password", password);

client.post(path, params, new AsyncHttpResponseHandler() {

@Override

//statusCode 是 響應(yīng)碼????????headers響應(yīng)頭???responseBody 響應(yīng)體

public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {

Toast.makeText(MainActivity.this,"登錄結(jié)果為"+new String(responseBody), 0).show();

}

@Override

public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {

Toast.makeText(MainActivity.this,"登錄結(jié)果為"+new String(responseBody), 0).show();

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容