您的位置:首页 > 其它

安卓学习记录(1)

2017-08-03 17:46 387 查看
intent的使用:跳转activity显示intent:Intent_intent=newIntent(firstActivity.this,SecActivity.class);startActivity(_intent);隐式intent:在Manifet文件内,在目标Activity的<intent-filter>标签内添加action和category,当_intent同时匹配action和category的时候,才會进行跳转(注意是同时匹配。)e.g.:
<activity…...>
<intent-filter>
<actionandroid:name="com.example.activitytest.ACTION_START"></action>
<categoryandroid:name="android.intent.category.DEFAULT"/>
<categoryandroid:name="sec_activity"/>
<categoryandroid:name="sec_activity_02”/>
</intent-filter>
</activity>
//进行跳转
Intent_intent=newIntent("com.example.activitytest.ACTION_START");
_intent.addCategory("sec_activity”);
_intent.addCategory("sec_activity_02”);
startActivity(_intent);
//如果找不到category同时具有sec_activity_02和sec_activity,并且action是com.example.activitytest.ACTION_START,则程序崩溃。
PS:除了category外,还可以添加data标签,用来响应intent
eg.:
..
<intent-filter>
<categoryandroid:name="android.intent.category.DEFAULT"/>
<dataandroid:scheme="https”/>//显示网页的时候,对应的activity可以选择响应
</intent-filter>
….
显示网页:
Intent_intent=newIntent(Intent.ACTION_VIEW);
_intent.setData(Uri.parse("https://www.baidu.com"));
startActivity(_intent);
拨打电话
Intentintent=newIntent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
使用intent获取下一级活动的数据(A->B,B->A),eg:
A:Intent_intent=newIntent(A.this,B.class);
startActivityForResult(_intent,1);
在B中对应的按钮响应方法或返回按钮响应函数中publicvoidonBackPressed(),实现代码:
Intent_intent=newIntent();
_intent.putExtra("number",“100");
setResult(RESULT_OK,_intent);
finish();
返回A时会调用onActivityResult函数,
@Overrite
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
//requestCode要与之前设置的请求码一致
if(requestCode==1){
Stringtest=data.getStringExtra(“number”);
Toast.makeText(Activity01.this,test,Toast.LENGTH_LONG).show();
}
}
在mainfest文件中,设置activity的android:launchMode属性,可控制activity的启动方式,
默认是standard(可重复创建然后启动)
singleTop(当前activity位于栈顶,直接使用当前活动,不会创建新的,但如果不是位于栈顶,则还是会创建新的。)
singleTask:上下文只会存在一个该类型的活动,不会重复,并且会把位于该activity之上的活动统统出栈
singleInstance:该activity会位于一个独立栈中,不与其他活动公用一个栈,e.g.:有A.B.C三个activity,B是singleInstance模式,即AC一个栈,B是另外一个栈
从A-》B,然后在B-》C,此时从C按返回键会回到A,在A中按返回键会到B中,在B中按返回键才會退出程序。
打印当前Activity名字:Log.i(”Activity”,getClass().getSimpleName());控件基本属性:hint(默认文本)在当前布局文件(xml文件)引用其他布局文件://title是布局文件title.xml
<includelayout="@layout/title"/>
隐藏导航栏:requestWindowFeature(Window.FEATURE_NO_TITLE);如果继承AppCompatActivity则无效,可使用:if(getSupportActionBar()!=null){getSupportActionBar().hide();} 碎片使用XML文件://left_fragment.xml
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:layout_gravity="center_horizontal"android:text="button"android:id="@+id/id_button"android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout>
新建LeftFragment类:
publicclassLeftFragmentextendsFragment{@OverridepublicViewonCreateView(LayoutInflaterlayoutInflater,ViewGroupparent,BundlesavedInstanceState){Viewv=layoutInflater.inflate(R.layout.left_fragment,parent,false);returnv;}}
//main_layout.xml:
…..。。正式使用
<fragmentandroid:name="com.example.shopins.fragmenttest.LeftFragment"android:id="@+id/id_left_fragment"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintRight_toLeftOf="@+id/id_right_layout"android:layout_width="0dp"app:layout_constraintHorizontal_weight="1"android:layout_height="0dp"></fragment>
…..
碎片替换:
//main_layout.xml文件
<FrameLayoutapp:layout_constraintHorizontal_weight="1"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toRightOf="@+id/id_left_fragment"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"android:id="@+id/id_right_layout"android:layout_width="0dp"android:layout_height="0dp”>
<fragmentandroid:name="com.example.shopins.fragmenttest.RightFragment"android:id="@+id/id_right_fragment"android:layout_width="match_parent"android:layout_height="match_parent”/>
</FrameLayout>
//MainActivity文件。。。。
AnotherRightFragmentnewFragment=newAnotherRightFragment();FragmentManagermanager=getFragmentManager();FragmentTransactiontransaction=manager.beginTransaction();
//按返回键的时候,返回上一个碎片,一般传入null
transaction.addToBackStack(null);
transaction.replace(R.id.id_right_layout,newFragment);transaction.commit();
。。。。//在活动中获取对应碎片实例,调用碎片实例方法:…..FragmentManagermanager=getFragmentManager();MyFragment_MyF=(MyFragment)manager.findFragmentById(R.id.fragmentid);_MyF.func();…..//在碎片中获取对应活动,调用活动实例方法:。。。。。。。
MainActivityactivity=(MainActivity)getActivity();
。。。。。。。 另外当碎片中需要使用Context对象时,也可以使用getActivity()方法,因为获取到的活动本身就是一个Context对象了。碎片的生命周期:从先到后依次为onAttach()当碎片和活动建立关联的时候调用。 onCreateView()为碎片创建视图(加载布局)时调用。 onActivityCreated()确保与碎片相关联的活动一定已经创建完毕的时候调用。 onDestroyView()当与碎片关联的视图被移除的时候调用。 onDetach()当碎片和活动解除关联的时候调用
在碎片中也可以用onSaveInstanceState()来保持数据。
在res目录下用限定符创建对应文件夹,设备可自动加载对应资源:
大小small供给小屏幕设备的资源
normal
供给中等屏幕设备的资源
large供给大屏幕设备的资源
xlarge
供给超大屏幕设备的资源
分辨率ldpi供给低分辨率设备的资源(120dpi 以下)
mdpi供给中等分辨率设备的资源(120dpi 到 160dpi) 
hdpi供给高分辨率设备的资源(160dpi 到 240dpi)
xhdpi供给超高分辨率设备的资源(240dpi 到 320dpi) 
方向land供给横屏设备的资源
port供给竖屏设备的资源
e.g.:当layout文件中有main_layout.xml文件,在res目录下新建layout-large文件夹,然后在里面新建main_layout.xml文件,那些屏幕被认为是large的设备就会自动加载layout-large文件夹下的布局,而小屏幕的设备则还是会加载layout文件夹下的布局。在res目录下,可以看到自动生成的mdpi、hdpi等文件夹如果希望自定义限定宽度,而不是系统认定的”large”,可使用最小宽度限定符,eg:加载activity_main布局的时候,先在res目录下新建layout-sw600dp,当程序运行在屏幕宽度大于600dp的设备上时,会加载layout-sw600dp/activity_main布局,当程序运行在屏幕宽度小于600dp的设备上时,则仍然加载默认的layout/activity_main布局广播分为有序广播和标准广播(无序)动态注册实现广播接收器:继承BroadcastReceiver并重写onReceive(Contextcontext,Intentintent)e.g.://在manifest文件内声明权限:<uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>….
protectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);intentFilter=newIntentFilter();
	//网络状态改变的时候接收通知intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");_receiver=newNetworkChangeReceiver();registerReceiver(_receiver,intentFilter);}classNetworkChangeReceiverextendsBroadcastReceiver{publicvoidonReceive(Contextcontext,Intentintent){Toast.makeText(MainActivity.this,"internetchanged!!!!",Toast.LENGTH_LONG).show();}}
….ps:动态注册后注意要撤销注册静态注册实现广播:这种方式可以使程序在未启动的情况下就能接收到广播e.g.://新建XXXX类(BootCompleteReceiver)
publicclassBootCompleteReceiverextendsBroadcastReceiver{@OverridepublicvoidonReceive(Contextcontext,Intentintent){Toast.makeText(context,"BootComplete",Toast.LENGTH_LONG).show();}}
//在mainfest文件中添加权限(开机启动)以及进行注册,android.intent.action.BOOT_COMPLETED(系统内置)
<uses-permissionandroid:name="android.permission.RECEIVE_BOOT_COMPLETED”/>
<receiverandroid:name=".BootCompleteReceiver"><intent-filter><actionandroid:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter></receiver>
//实现:
….
Intentintent=newIntent("android.intent.action.BOOT_COMPLETED");
sendBroadcast(intent);
…..
自定义广播:
//新建XXXX类(BootCompleteReceiver)
publicclassBootCompleteReceiverextendsBroadcastReceiver{@OverridepublicvoidonReceive(Contextcontext,Intentintent){Toast.makeText(context,"BootComplete",Toast.LENGTH_LONG).show();}}
//manifest文件注册:
<receiverandroid:name=".BootCompleteReceiver"><intent-filter><actionandroid:name="my_broadcast"/></intent-filter></receiver>
//实现:
BootCompleteReceiverreceive=newBootCompleteReceiver();
Intentintent=newIntent(“my_broadcast”)
//只要注册my_broadcast的,都能接收到
sendBroadcast(receive,intent);
特别:在广播接收器中是不能开启线程的有序广播:实现方式与自定义相同,区别用sendOrderedBroadcast(第二个参数是一个与权限相关的字符串,可以传入null)代替sendBroadcast。ps:因为有序关系,前面的广播接收器可以将广播截断,以阻止其继续传播,实现方式是在onReceive()方法中调用了abortBroadcast()方法,就表示将这条广播截断,后面的广播接收器将无法再接收到这条广播ps:如何设置广播顺序?只需要在manifest中设置权限优先级,优先级比较高的先收到广播,eg: <receiverandroid:name=".MyBroadcastReceiver"><intent-filterandroid:priority="100"><actionandroid:name="MY_BROADCAST"/></intent-filter></receiver>
上面的属于系统全局广播,即发出的广播可以被其他任何的任何应用程序接收到
本地广播:只能在该程序内部进行传递。主要通过LocalBroadcastManager进行管理,并提供发送和接收广播的方法
e.g.:
privateMyLocalService_service;privateLocalBroadcastManagerlocalBroadcastManager;privateIntentFilterintentFilter;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);_service=newMyLocalService();localBroadcastManager=LocalBroadcastManager.getInstance(this);Buttonbtn=(Button)findViewById(R.id.id_btn);btn.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){Intentintent=newIntent("My_Local");localBroadcastManager.sendBroadcast(intent);}});intentFilter=newIntentFilter();intentFilter.addAction("My_Local");localBroadcastManager.registerReceiver(_service,intentFilter);}classMyLocalServiceextendsBroadcastReceiver{@OverridepublicvoidonReceive(Contextcontext,Intentintent){Toast.makeText(MainActivity.this,"thisislocalmessage",Toast.LENGTH_LONG).show();}}
ps:不需要去manifest注册
访问http://developer.android.com/reference/android/Manifest.permission.html可以查看Android系统所有可声明的权限数据持久化:文件存储、数据库存储、sharePreference 文件存取://保存
publicvoidsave(){Stringdata="Datatosave";FileOutputStreamout=null;BufferedWriterwriter=null;try{		
	out=openFileOutput("data",Context.MODE_PRIVATE);
writer=newBufferedWriter(newOutputStreamWriter(out));writer.write(data);	
}catch(IOExceptione){e.printStackTrace();
}finally{
try{
if(writer!=null){
writer.close();
}}catch(IOExceptione){				
e.printStackTrace();}
}}//读取
publicStringload(){FileInputStreamin=null;BufferedReaderreader=null;StringBuildercontent=newStringBuilder();try{
in=openFileInput("data");
reader=newBufferedReader(newInputStreamReader(in));Stringline=“”;
while((line=reader.readLine())!=null){content.append(line);
}}catch(IOExceptione){			
e.printStackTrace();}finally{			
if(reader!=null){try{	
reader.close();}catch(IOExceptione){				
e.printStackTrace();}	
}} returncontent.toString();} SharedPreferences:使用键值对的方式来存储数据的。也就是说当保存一条数据的时候,需要给这条数据供一个对应的键获取sharepreferences对象的三种方法:1.Context类中的getSharePreferences()方法,传入两个参数,第一个是文件名,第2个是操作模式(MODE_PRIVATE和MODE_MULTI_PROCESS,MODE_PRIVATE表示只有当前程序才能对该文件进行读写)2.Activity类中的getPreferences()方法,传入操作模式,默认文件名是当前活动类名3.PreferenceManager类中的getDefaultSharePreferences()方法 得到了SharedPreferences对象之后,就可以开始向SharedPreferences文件中存储数据了,主要可以分为三步实现。调用SharedPreferences对象的edit()方法来获取一个SharedPreferences.Editor对象。向SharedPreferences.Editor对象中添加数据,比如添加一个布尔型数据就使用putBoolean方法,添加一个字符串则使用putString()方法,以此类推。调用commit()方法将添加的数据交,从而完成数据存储操作e.g.://保存
SharedPreferences.Editoreditor=getSharedPreferences("data",MODE_PRIVATE).edit();editor.putString("keep",text);editor.commit();
//读取
TextViewv=(TextView)findViewById(R.id.id_textview);SharedPreferencessharedPreferences=getSharedPreferences("data",MODE_PRIVATE);Stringdata=sharedPreferences.getString("keep","null");v.setText(data.toString());
使用数据库:SQLiteOpenHelpere.g.:新建数据库工具类(继承SQLiteOpenHelper)
publicclassMyDatabaseHelperextendsSQLiteOpenHelper{//版本1//publicstaticfinalStringCREATE_BOOK="createtableBook("+//"idintegerprimarykeyautoincrement,"//+"authortext,"//+"pricereal,"//+"pagesinteger,"//+"nametext)";//版本3publicstaticfinalStringCREATE_BOOK="createtableBook("+"idintegerprimarykeyautoincrement,"+"authortext,"+"pricereal,"+"pagesinteger,"+"nametext,"+"category_idinteger)";publicstaticfinalStringCREATE_CATEGORY="createtableCategory("+"idintegerprimarykeyautoincrement,"+"category_nametext,"+"category_codeinteger)";privateContextmContext;publicMyDatabaseHelper(Contextcontext,Stringname,SQLiteDatabase.CursorFactoryfactory,intversion){super(context,name,factory,version,null);mContext=context;}@Override//如果用户是从版本2开始安装程序,那么会创建两个表publicvoidonCreate(SQLiteDatabasedb){db.execSQL(CREATE_BOOK);db.execSQL(CREATE_CATEGORY);Toast.makeText(mContext,"Createsucceeded",Toast.LENGTH_SHORT).show();}@Override//对数据库进行升级时候调用,当初始化传入的版本号高于之前的,就会升级publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){switch(oldVersion){//如果用户已经安装版本1,现在更新到版本2,只需要再创建第2个表case1:db.execSQL(CREATE_CATEGORY);break;//用户从版本2更新到版本3case2:db.execSQL("altertableBookaddcolumncategory_idinteger");break;default:}}}
//activity文件
privateMyDatabaseHelpermyDatabaseHelper;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);myDatabaseHelper=newMyDatabaseHelper(this,"BookStore.db",null,2);setContentView(R.layout.activity_main);//创建表finalButtoncreateDatabase=(Button)findViewById(R.id.create_database);createDatabase.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){myDatabaseHelper.getWritableDatabase();}});//添加ButtonaddData=(Button)findViewById(R.id.add_data);addData.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){SQLiteDatabasedb=myDatabaseHelper.getWritableDatabase();ContentValuesvalues=newContentValues();//开始组装第一条数据values.put("name","TheDaVinciCode");values.put("author","DanBrown");values.put("pages",454);values.put("price",16.96);db.insert("Book",null,values);//插入第一条数据values.clear();//开始组装第二条数据values.put("name","TheLostSymbol");values.put("author","DanBrown");values.put("pages",510);values.put("price",19.95);db.insert("Book",null,values);}});//更新数据ButtonupdateData=(Button)findViewById(R.id.update_data);updateData.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){SQLiteDatabasedb=myDatabaseHelper.getWritableDatabase();ContentValuescontentValues=newContentValues();contentValues.put("price",10.99);db.update("Book",contentValues,"name=?",newString[]{"TheDaVinciCode"});}});//删除ButtondeleteButton=(Button)findViewById(R.id.delete_data);deleteButton.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){SQLiteDatabasedb=myDatabaseHelper.getWritableDatabase();db.delete("Book","pages>?",newString[]{"500"});}});//查询ButtonqueryButton=(Button)findViewById(R.id.query_data);queryButton.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){SQLiteDatabasedb=myDatabaseHelper.getWritableDatabase();Cursorcursor=db.query("Book",null,null,null,null,null,null);if(cursor.moveToFirst()){do{Stringname=cursor.getString(cursor.getColumnIndex("name"));Stringauthor=cursor.getString(cursor.getColumnIndex("author"));intpages=cursor.getInt(cursor.getColumnIndex("pages"));doubleprice=cursor.getDouble(cursor.getColumnIndex("price"));Log.w("MainActivity","booknameis"+name);Log.w("MainActivity","bookauthoris"+author);Log.w("MainActivity","bookpagesis"+pages);}while(cursor.moveToNext());cursor.close();}}});}
//XML文件
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/create_database"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Createdatabase"/><Buttonandroid:id="@+id/add_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Adddata"/><Buttonandroid:id="@+id/update_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Updatedata"/><Buttonandroid:id="@+id/delete_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Deletedata"/><Buttonandroid:id="@+id/query_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Querydata"/></LinearLayout>
SQL需要注意大小写,比如Book和book不一样。SQLite支持事务,事务可保证操作全部完成或者操作一步都没有进行。如何进行事务操作?从SQLiteOpenHelper对象的beginTransaction方法开始,以SQLiteOpenHelper对象的setTransactionSuccessful结束。e.g.:SQLiteDatabasedb=dbHelper.getWritableDatabase();db.beginTransaction();//开启事务try{ db.delete("Book",null,null);//if(true){ //在这里手动抛出一个异常,让事务失败 //thrownewNullPointerException();
//}				
ContentValuesvalues=newContentValues();values.put("name","GameofThrones");values.put("author","GeorgeMartin");values.put("pages",720);values.put("price",20.85);db.insert("Book",null,values);db.setTransactionSuccessful();//事务已经执行成功}catch(Exceptione){
e.printStackTrace();
		}finally{
db.endTransaction();//结束事务}内容提供器(ContentProvider)主要用于在不同的应用程序之间实现数据共享的功能,它供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性,个人理解,其实就是给外部程序提供访问程序内部数据的接口,令外部程序可以增删改查程序内部的数据内容提供器的用法一般有两种,一种是使用现有的内容供器来读取和操作相应程序中的数据,另一种是创建自己的内容供器给我们程序的数据供外部访问接口。类似电话簿、媒体库等都使用了内容提供器主要使用ContentResolve类,它的增删改查方法接收Uri对象,而Uri对象字符串有两部分构成,权限和路径,一般权限是包名,路径是表名,前面还需要加上协议。 内容URI最标准的格式写法如下: content://com.example.app.provider/table1content://com.example.app.provider/table2使用内容提供器,需要在manifest文件声明权限,eg:自定义内容提供器
<providerandroid:name="com.example.demo.DatabaseProvider"android:authorities="com.example.demo.provider"/>
使用了<provider>标签来对DatabaseProvider这个内容供器进行注册,在android:name属性中指定了该类的全名,又在android:authorities属性中指定了该内容提供器的权限
notification通知(效果类似push通知):通过notificationmanager进行管理,一般通过getSystemService获取。e.g.: NotificationManagermanager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);基本使用:NotificationManagermanager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);//设置点击通知后跳转的activityIntent_itent=newIntent(this,OtherActivity);PendingIntentpendingIntent=PedingIntent.getActivity(this,0,_intent,PendingIntent.FLAG_IMMUTABLE);//初始化Notification对象,Build传入context对象,setSound这是声音Notification_notification=newNotification.Build(this).setContentTitle(“title”).setContentText(“text”).setContentIntent(pendingIntent).setSmallIcon(R.mipmap.xx).setSound(Uri.fromFile(newFile("/system/media/audio/ringtones/Basic_tone.ogg"))).build();
//自定义行为
//设置手机振动,下标0是手机静止时长,下标1是手机振动时长,下标2又是手机静止时长,以此类推,单位是毫秒,该功能需要权限:<uses-permissionandroid:name="android.permission.VIBRATE"/>
long[]vibrates={0,1000,1000,1000};notification.vibrate=vibrates;
//闪光灯颜色notification.ledARGB=Color.GREEN;//闪光灯暗去,单位:毫秒notification.ledOnMS=1000;//闪光灯亮起notification.ledOffMS=1000;//指定通知行为notification.flags=Notification.FLAG_SHOW_LIGHTS;
//或者不自定义,设置全部默认行为。
//notification.defaults=Notification.DEFAULT_ALL;
//传入id和notification对象manager.notify(1,_notification)ps:如果希望点击之后消除通知,需要在对应的活动调用notificationManager.cancel(id).eg:在上例中OtherActivity:
@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.notification_layout);NotificationManagermanager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);manager.cancel(1);}
获取短信:
privateTextViewsender;privateTextViewcontent;privateIntentFilterintentFilter;privateMessageReceivermessageReceiver;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sender=(TextView)findViewById(R.id.id_sender);content=(TextView)findViewById(R.id.id_content);intentFilter=newIntentFilter();
//设置优先级,保证第一个接收到intentFilter.setPriority(100);
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");messageReceiver=newMessageReceiver();registerReceiver(messageReceiver,intentFilter);}@Override
//activity文件protectedvoidonDestroy(){super.onDestroy();unregisterReceiver(messageReceiver);}classMessageReceiverextendsBroadcastReceiver{@OverridepublicvoidonReceive(Contextcontext,Intentintent){Bundlebundle=intent.getExtras();Object[]obj=(Object[])bundle.get("pdus");SmsMessage[]smsMessage=newSmsMessage[obj.length];for(inti=0;i<smsMessage.length;i++){smsMessage[i]=SmsMessage.createFromPdu((byte[])obj[i]);}Stringaddress=smsMessage[0].getOriginatingAddress();StringfullMessage="";for(SmsMessagemessage:smsMessage){fullMessage+=message.getMessageBody();}sender.setText(address.toString());content.setText(fullMessage.toString());
//拦截通知,不可以继续下发abortBroadcast();
}}
//manifest文件设置权限
<uses-permissionandroid:name="android.permission.RECEIVE_SMS"/>
多线程:1.继承线程类Thread,重写run2.实现接口Runnable,重写run3.在实例化Thread类的时候,定义了一个实现Runnable接口的匿名内部类,eg:newThread(newRunnable(){
@Overridepublicvoidrun(){……..}}).start();
更新UI的时候只能在主线程里更新。异步消息处理分四部分:Handle,Message,Looper,MessageQueue4.使用AsyncTaskAsyncTask: 为UI线程与工作线程之间进行快速的切换提供一种简单便捷的机制。适用于当下立即需要启动,但是异步执行的生命周期短暂的使用场景。AsyncTask的使用:继承的时候指定三个范型,
Params:在执行AsyncTask需要传入的参数,可用于后台任务中使用。Progress:后台执行任务时,如果需要在界面显示当前进度,可以设置为进度单位。Result:当任务结束时,如果需要返回,可以使用这里的范型作为返回类型publicclassMyAsyncTaskextendsAsyncTask<Void,Integer,Boolean>{@WorkerThreadprotectedBooleandoInBackground(Void...params){这里执行所有耗时操作,但是因为不是主线程,所以不能进行界面操作返回值和继承范型Result的类型是一致的。如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress...)方法来完成。returntrue;}@MainThread这个方法在后台执行前调用,一般用于进行界面一些初始化操作,比如显示一个进度条protectedvoidonPreExecute(){}@MainThreadprotectedvoidonPostExecute(Resultresult){当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如说醒任务执行的结果,以及关闭掉进度条对话框等。}@MainThreadprotectedvoidonProgressUpdate(Integer...values){当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就会很快被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值就可以对界面元素进行相应地更新}@MainThreadprotectedvoidonCancelled(Resultresult){onCancelled();}}
使用:newMyAsyncTask().execute();
自定义服务,并有下载功能:
publicclassMyServiceextendsService{privateDownloadBindermBinder=newDownloadBinder();classDownloadBinderextendsBinder{publicvoidstartDownload(){Log.d("MyService","startDownloadexecuted");}publicintgetProgress(){Log.d("MyService","getProgressexecuted");return0;}}@OverridepublicIBinderonBind(Intentintent){Log.w("onBind",getClass().getSimpleName());returnmBinder;}@Override,如果初始化,则首先执行。publicvoidonCreate(){Log.w("onCreate",getClass().getSimpleName());}@Override,startService后调用,如果该服务还没创建,则该方法在onCreate后调用。publicintonStartCommand(Intent_intent,intflags,int_startID){Log.w("onStartCommand",getClass().getSimpleName());returnsuper.onStartCommand(_intent,flags,_startID);}@OverridepublicvoidonDestroy(){Log.w("onDestroy",getClass().getSimpleName());super.onDestroy();}}
使用:
1.先声明一个ServiceConnection对象:
privateMyService.DownloadBinderdownloadBinder;
privatefinalServiceConnectionserviceConnection=newServiceConnection(){@OverridepublicvoidonServiceConnected(ComponentNamename,IBinderservice){downloadBinder=(MyService.DownloadBinder)service;downloadBinder.startDownload();downloadBinder.getProgress();}@OverridepublicvoidonServiceDisconnected(ComponentNamename){}};
2.执行执行绑定:
Intentbind=newIntent(this,MyService.class);bindService(bind,serviceConnection,BIND_AUTO_CREATE);
3.接触绑定:
Intentunbind=newIntent(this,MyService.class);unbindService(serviceConnection);
需要声明权限:
<serviceandroid:name=".MyService"/>
一种异步、自动停止的服务:IntentService IntentService: 适合于执行由UI触发的后台Service任务,并可以把后台任务执行的情况通过一定的机制反馈给UI。e.g.:...
publicclassMyIntentServiceextendsIntentService{publicMyIntentService(){super("MyIntentService");}@OverridepublicIBinderonBind(Intentintent){returnnull;}//@WorkerThreadprotectedvoidonHandleIntent(Intentintent){Log.w("onHandleIntent","Threadidis"+Thread.currentThread().getId());}}
..
//在manifest文件注册权限:
<serviceandroid:name=".MyIntentService"/>
使用:
IntentintentService=newIntent(this,MyIntentService.class);
startService(intentService);
延时操作(定时任务):开启新线程 newThread(newRunnable(){    publicvoidrun(){      Thread.sleep(XXXX);      handler.sendMessage();//告诉主线程执行任务    }  }).start 利用定时器TimerTasktask=newTimerTask(){    publicvoidrun(){    //executethetask   }  };  Timertimer=newTimer(); timer.schedule(task,delay); // newHandler().postDelayed(newRunnable(){    publicvoidrun(){    //executethetask    }   },delay);  利用AlarmManager,用于长时间、复杂的任务。 
HttpsURLConnection的使用。
e.g.:
privatestaticfinalintSHOW_RESPONSE=0;privateButtonsendRequest;privateTextViewresponseText;privateHandlerhandler=newHandler(){publicvoidhandleMessage(Messagemsg){switch(msg.what){caseSHOW_RESPONSE:StringBuilderstr=(StringBuilder)msg.obj;responseText.setText(str.toString());break;default:break;}}};@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sendRequest=(Button)findViewById(R.id.id_send_request);responseText=(TextView)findViewById(R.id.id_response);sendRequest.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){sendRequestWithHttpURLConnection();}});}publicvoidsendRequestWithHttpURLConnection(){newThread(newRunnable(){@Overridepublicvoidrun(){HttpsURLConnectionconnection=null;try{URLurl=newURL("https://www.baidu.com");connection=(HttpsURLConnection)url.openConnection();connection.setConnectTimeout(8000);connection.setReadTimeout(8000);connection.setRequestMethod("GET");InputStreaminputStream=connection.getInputStream();BufferedReaderbufferedReader=newBufferedReader(newInputStreamReader(inputStream));StringBuilderstringBuilder=newStringBuilder();Stringline="";while((line=bufferedReader.readLine())!=null){stringBuilder.append(line);}Messagemessage=newMessage();message.what=SHOW_RESPONSE;message.obj=stringBuilder;handler.sendMessage(message);}catch(Exceptione){e.printStackTrace();}finally{if(connection!=null){connection.disconnect();}}}}).start();}
解析JSON使用JSONObjecte.g.://JSON数据
[{"id":"5","version":"5.5","name":"AngryBirds"},{"id":"6","version":"7.0","name":"ClashofClans"},{"id":"7","version":"3.5","name":"HeyDay”}]
//jsonData的值打印出来跟上面一致。
privatevoidparseJSONWithJSONObject(StringjsonData){
try{
JSONArrayjsonArray=newJSONArray(jsonData);for(inti=0;i<jsonArray.length();i++){
JSONObjectjsonObject=jsonArray.getJSONObject(i);
Stringid=jsonObject.getString("id");Stringname=jsonObject.getString("name");Stringversion=jsonObject.getString("version");Log.d("MainActivity","idis"+id);Log.d("MainActivity","nameis"+name);
}}catch(Exceptione){
e.printStackTrace();}
}添加jar方式:1.赋值jar包到libs文件夹下,2.在androidstudio找到加入的jar包,右键选择addaslibrary,然后添加详细:http://www.cnblogs.com/neozhu/p/3458759.html使用Json解析轮子GSON:https://github.com/google/gson下载地址:http://search.maven.org/#artifactdetails%7Ccom.google.code.gson%7Cgson%7C2.8.1%7Ce.g.:网络功能轮子:OkHttp:http://square.github.io/okhttp/或者https://github.com/square/okhttp用法:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html网络编程最佳实践://自定义网络工具类
publicclassHttpService{publicinterfaceHttpCallbackListener{voidonFinish(Stringresponse);voidonError(Exceptione);}publicstaticvoidsendHttpRequest(finalStringaddress,finalHttpCallbackListenerlistener){newThread(newRunnable(){@Overridepublicvoidrun(){HttpURLConnectionconnection=null;try{URLurl=newURL(address);connection=(HttpURLConnection)url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);connection.setDoInput(true);connection.setDoOutput(true);InputStreamin=connection.getInputStream();BufferedReaderreader=newBufferedReader(newInputStreamReader(in));StringBuilderresponse=newStringBuilder();Stringline;while((line=reader.readLine())!=null){response.append(line);}if(listener!=null){//回调onFinish()方法listener.onFinish(response.toString());}}catch(Exceptione){if(listener!=null){//回调onError()方法 
		listener.onError(e);}}finally{if(connection!=null){connection.disconnect();}}}}).start();}
}使用:HttpService.sendHttpRequest(“https://www.baidu.com",newHttpService.HttpCallbackListener(){
@OverridepublicvoidonFinish(Stringresponse){}@OverridepublicvoidonError(Exceptione){}});
反向地理编码:使用GeocodingApi使用GeoCoder也提供正向和反向的地理编码功能,但是有bug:有一定概率地理位置解析失败,所以使用GeocodingAPI比较稳定https://developers.google.com/maps/documentation/geocoding/。GeocodingAPI中规定了很多接口,其中反向地理编码的接口如下:http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true_or_false设置获取全局Content的方法1.自定义MyApplication继承Application2.让程序初始化自定义的MyApplication(而不是Application),需要在manifest文件中进行修改注册说明3.在MyApplication中重写onCreate方法,调用Application的getApplicationContext方法赋值给自定义的static变量。e.g.: //需要在manifest文件内,添加注册声明
publicclassMyApplicationextendsApplication{privatestaticContextcontext;	
	@OverridepublicvoidonCreate(){
context=getApplicationContext();}			
publicstaticContextgetContext(){returncontext;			
}}ps:可以在自定义的application类中,定义一些全局变量。使用intent来传递自定义对象:Serializeble方式和parcelable方式Serializeble方式:1。自定义对象实现Serializeble2.获取对象时候intent调用getSerializableExtra方法获取。e.g.:
publicclassPersonimplementsSerializable{
	privateStringname;
privateintage;			
publicStringgetName(){returnname;			
} publicvoidsetName(Stringname){this.name=name; }publicintgetAge(){returnage; } publicvoidsetAge(intage){this.age=age; }}//使用Personperson=newPerson();
person.setName("Tom");person.setAge(20);Intentintent=newIntent(FirstActivity.this,SecondActivity.class);intent.putExtra("person_data",person);	
startActivity(intent);
//获取对象
Personperson=(Person)getIntent().getSerializableExtra("person_data");
parcelable方式:将对象进行分解,分解后的每一个部分都是intent所支持的数据类型。parcelable比Serializeble的效率要高一点,但更加复杂e.g.:
publicclassPersonimplementsSerializable{
	privateStringname;
privateintage;
	publicStringgetName(){returnname;			
} publicvoidsetName(Stringname){this.name=name; }publicintgetAge(){returnage; } publicvoidsetAge(intage){this.age=age; }
	@OverridepublicintdescribeContents(){	
return0;}@OverridepublicvoidwriteToParcel(Parceldest,intflags){ dest.writeString(name);//写出namedest.writeInt(age);//写出age}publicstaticfinalParcelable.Creator<Person>CREATOR=newParcelable. Creator<Person>(){ @OverridepublicPersoncreateFromParcel(Parcelsource){ Personperson=newPerson();person.name=source.readString();//读取name person.age=source.readInt();//读取age returnperson;}@OverridepublicPerson[]newArray(intsize){
returnnewPerson[size];}		
};}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: