一、将数据存储到文件中
Context类中提供了一个openFileOutput()方法,可以将数据存储到指定的文件中。接受两个参数,第一个是文件名,第二个是文件的操作模式,主要有两种可选,MODE_PRIVATE和MODE_APPEND。MODE_ORIVATE表示覆盖内容,MODE_APPEND表示追加内容。两种模式都会在文件不存在的时候闯将文件。
public void Save(String inputText) { FileOutputStream out = null; BufferedWriter writer = null; try { out = openFileOutput("data", Context.MODE_PRIVATE); writer = new BufferedWriter(new OutputStreamWriter(out)); writer.write(inputText); }catch (IOException e) { e.printStackTrace(); } finally { try{ if(writer != null) writer.close(); }catch (IOException e) { e.printStackTrace(); } } } protected void onDestroy() { super.onDestroy(); Save(edit.getText().toString()); }
二、从文件中读取数据
Context类中提供了一个openFileInput()方法,用于从文件中读取数据,接受一个文件名参数。
public String load() { FileInputStream in = null; BufferedReader reader = null; StringBuilder content = new StringBuilder(); try{ in = openFileInput("data"); reader = new BufferedReader(new InputStreamReader(in)); String line = ""; while((line = reader.readLine()) != null) { content.append(line); } }catch (IOException e) { e.printStackTrace(); } finally { try{ reader.close(); } catch (IOException e) { e.printStackTrace(); } } return content.toString(); } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView((R.layout.first_layout)); edit = (EditText) findViewById(R.id.edit); String inputText = load(); if(!TextUtils.isEmpty(inputText)) { edit.setText(inputText); edit.setSelection(inputText.length()); Toast.makeText(Main2Activity.this,"加载数据成功",Toast.LENGTH_SHORT).show(); } }
使用本地广播可以避免广播被其他任何应用程序接收到,同时广播接收器也只能接收来自本应发出的广播,这样就可以避免其他应用程序广播的污染了。
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView((R.layout.first_layout)); localBroadcastManager = LocalBroadcastManager.getInstance(Main2Activity.this); rece = new BootCompleteReceiver(); IntentFilter iF = new IntentFilter(); iF.addAction("group.chicai.study.JJJ"); localBroadcastManager.registerReceiver(rece,iF); Button button9 = (Button)findViewById(R.id.button9); button9.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent("group.chicai.study.JJJ"); localBroadcastManager.sendBroadcast(intent); } }); } protected void onDestroy() { super.onDestroy(); localBroadcastManager.unregisterReceiver(rece); }
public class BootCompleteReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"啦啦啦空间啊沙发哈会计法哈克金凤凰",Toast.LENGTH_LONG).show(); } }
一、多个广播接收器
public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"接受到我的广播",Toast.LENGTH_SHORT).show(); abortBroadcast();//截断消息广播 } } public class MyReceiver2 extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"接受自定义2",Toast.LENGTH_SHORT).show(); } }
二、注册广播接收器,并指定接收顺序。android:priority越高表示优先通知
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="100"> <action android:name="group.chicai.study.MYBOASTCASE" /> </intent-filter> </receiver> <receiver android:name=".MyReceiver2" android:enabled="true" android:exported="true" > <intent-filter android:priority="99"> <action android:name="group.chicai.study.MYBOASTCASE" /> </intent-filter> </receiver>
三、发送有序广播
Button button8 = (Button)findViewById(R.id.button8); button8.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent("group.chicai.study.MYBOASTCASE"); sendOrderedBroadcast(intent,null);//就是换了个方法发送 } });
标准广播是一种完全异步执行的广播,广播发出后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息。无法被截断。
一、新建广播接收器,右键New->Other->Broadcast Receiver,就会创建一个广播接收器
package group.chicai.study; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"接受到我的广播",Toast.LENGTH_SHORT).show(); abortBroadcast(); } }
二、注册这个广播接收器的触发行为
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter ><!-- 静态注册 --> <action android:name="group.chicai.study.MYBOASTCASE" /> </intent-filter> </receiver>
//动态注册 intentFilter = new IntentFilter(); intentFilter.addAction("group.chicai.study.MYBOASTCASE"); MyReceiver my = new MyReceiver(); registerReceiver(my,intentFilter);
三、发送广播
Button button8 = (Button)findViewById(R.id.button8); button8.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent("group.chicai.study.MYBOASTCASE"); sendBroadcast(intent); } });
同样的,系统上定义了很多检查状态改变的action,可以让接收器去注册这个行为,这样当系统的某些状态改变时,就会触发这些接收器了。例如:网络改变的监督-android.net.conn.CONNECTIVITY_CHANGE
public class SystemUtil { /* *获取电量 context为UnityPlayer.currentActivity 。 */ public static float MonitorBatteryState(Context context) { IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); Intent intent = context.registerReceiver(null, iFilter); int rawLevel = intent.getIntExtra("level", 0); //获得当前电量 int scale = intent.getIntExtra("scale", 0); //获得总电量 //int status = intent.getIntExtra("status", 0); //电池充电状态 return (float)rawLevel / (float)scale; } //获取Wifi信号强度 context为UnityPlayer.currentActivity 。 @SuppressWarnings("deprecation") public static int ObtainWifiInfo(Context context) { int strength = 0; WifiManager wifiManager = (WifiManager)context.getSystemService(WIFI_SERVICE); WifiInfo info = wifiManager.getConnectionInfo(); if(info.getBSSID() != null) { //链接信号强度 strength = WifiManager.calculateSignalLevel(info.getRssi(), 5); } return strength; } //获取手机网络信号 context为UnityPlayer.currentActivity 。 public static int getMobileSignLevel(Context context) { int dbm = -1; int level = 0; TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); List<CellInfo> cellInfoList = tm.getAllCellInfo(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { if (null != cellInfoList) { for (CellInfo cellInfo : cellInfoList) { if (cellInfo instanceof CellInfoGsm) { CellSignalStrengthGsm cellSignalStrengthGsm = ((CellInfoGsm)cellInfo).getCellSignalStrength(); level = cellSignalStrengthGsm.getLevel(); } else if (cellInfo instanceof CellInfoCdma) { CellSignalStrengthCdma cellSignalStrengthCdma = ((CellInfoCdma)cellInfo).getCellSignalStrength(); level = cellSignalStrengthCdma.getLevel(); } else if (cellInfo instanceof CellInfoWcdma) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { CellSignalStrengthWcdma cellSignalStrengthWcdma = ((CellInfoWcdma)cellInfo).getCellSignalStrength(); level = cellSignalStrengthWcdma.getLevel(); } } else if (cellInfo instanceof CellInfoLte) { CellSignalStrengthLte cellSignalStrengthLte = ((CellInfoLte)cellInfo).getCellSignalStrength(); level = cellSignalStrengthLte.getLevel(); } } } } return level; } }
可以在AndroidManifiest.xml文件中设置活动的启动模式
<activity android:name=".Main23Activity" android:launchMode="singleTop"> </activity>
一共有四种启动模式:
一、standard,Android默认的启动模式,对于这种活动,每次启动都会创建一个新的实例到返回栈中。
二、singleTop,对于这种模式的活动,启动时会先去返回栈栈顶中检查是否是这个活动,是的话就直接使用它,否则就会创建新的实例。
三、singleTask,对于这种模式的活动,只要返回栈中存在这个活动,都会启用它,如果没有才会创建新的实例。
四、singleInstance,对于这种模式的活动,会使用一个单独的返回栈来管理这种活动。
Android的活动是可以层叠的。Android使用任务(Task)来管理活动,一个任务就是一组存放在栈里的活动的集合,这个栈叫做返回栈。
活动类中定义了7个回调方法,覆盖了活动生命周期的每一个环节。
onCreate(),它会在活动第一次被创建的时候调用,在这里完成活动的初始化操作,比如加载布局、绑定事件等。
onStart(),它会在活动由不可见变为可见的时候调用。
onResume(),它会在活动准备好和用户交互的时候调用。此时活动一定位于返回栈的栈顶,并且处于运行状态。
onPause(),这个方法在系统准备去启动或恢复另一个活动的时候调用。通常做一些释放资源和保存关键数据的操作,执行速度要快。
onStop(),这个方法在活动完全不可见的时候调用,和onPause的主要区别在于,启动的活动为对话框时,onPause会执行,onStop不会执行
onDestroy(),这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。
onRestart(),这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。
一、向下一个活动传递数据
Button button3 = (Button) findViewById(R.id.button3); button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Main2Activity.this,Main23Activity.class); intent.putExtra("name","chicai");//向intent添加参数,key,value形式 startActivity(intent); } });
public class Main23Activity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main23); Intent intent = getIntent(); TextView text = (TextView) findViewById(R.id.textView); text.setText(intent.getStringExtra("name")); } }
二、向上一个活动传递数据
Button button3 = (Button) findViewById(R.id.button3); button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Main2Activity.this,Main23Activity.class); intent.putExtra("name","chicai"); startActivityForResult(intent,1);//意思了开启一个活动用来获取结果的,1是用来辨识不同的这种Activity } });
//用这个活动设置返回结果,然后结束就会传递到上一个活动了 public class Main23Activity extends AppCompatActivity { @Override protected void onStart() { super.onStart(); Button button = (Button)findViewById(R.id.button7); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); intent.putExtra("return_val","memeda"); setResult(RESULT_OK,intent);//设置结果 finish(); } }); } }
//返回上一个活动,通过onActivityResult接收 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch(requestCode) { case 1: if(resultCode == RESULT_OK) { String str = data.getStringExtra("return_val"); TextView text = (TextView) findViewById(R.id.textView2); text.setText(str); } break; } }
例如我要在浏览器中打开一个网址,我们就可以这样写一个Intent。当手机上的应用有声明这个Action为android.intent.action.VIEW并且data的声明的scheme为http的活动时,就会被相应的激活。
Button button5 = (Button)findViewById(R.id.button5); button5.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Intent.ACTION_VIEW);//android.intent.action.VIEW intent.setData(Uri.parse("http://www.chicai.group"));//设置一个uri startActivity(intent); } });
intent.setData对应的声明就是data标签写的属性 :
android:scheme用于指定数据的协议部分,如http
android:host用于指定数据的主机名部分,如www.chicai.group
android:port用于指定数据的端口部分
android:path用于指定主机名和端口之后的部分
android:mimeType用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
<intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="http" android:host="主机名" android:path="/open"/> </intent-filter>
再例如打电话:
Button button6 = (Button)findViewById(R.id.button6); button6.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:10086")); startActivity(intent); } });
Intent是Android程序中各组件之间进行交互的一种重要方式,不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用于启动活动、启动服务以及发送光比等场景。可以通过Intent从一个活动跳转到另外一个活动,实现活动和活动之间的交换。
一、显式Intent
Button button3 = (Button) findViewById(R.id.button3); button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //第一个参数为启动活动的上下文,第二个为需要启动的目标活动 Intent intent = new Intent(Main2Activity.this,Main23Activity.class); startActivity(intent);//启动目标活动 } });
二、隐式Intent
在配置文件AndroidManifest.xml中,配置一些activity的参数,通过这些行为参数来让Android来判断是否启动这个活动。需要同时满足这些条件才会激活这个活动。category是可以添加多个的。
<activity android:name=".Main23Activity"> <intent-filter> <action android:name="group.chicai.study.ACTION_START"></action> <category android:name="android.intent.category.DEFAULT"></category> </intent-filter> </activity>
Button button4 = (Button) findViewById(R.id.button4); button4.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent("group.chicai.study.ACTION_START"); intent.addCategory("android.intent.category.DEFAULT"); startActivity(intent); } });