#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();
}