手機衛士-01
課1
課程介紹
課2
新建項目phoneSafeguard
需求1:打開軟件可以顯示一個歡迎界面,一般是公司的logo
SplashActivity.java
public class SplashActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//設置沒有標題,以下兩行代碼順序注意
requestWindowFeature(Window.FEATURE_NO_TITLE);//設置歡迎界面
setContentView(R.layout.activity_splash);
// JSONObject json = new JSONObject();
}
}
activity_splash.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#88000000" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:layout_centerInParent="true"
/>
<ProgressBar />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="版本號"/>
</RelativeLayout>
json:
(JavaScript object Notation)是一種輕量級的數據交換形式。易於人閱讀和編寫。同時是易於機器解析和編寫
xml(傳輸數據耗流量) 例如: zhangsan
以上都用來傳輸數據
演示json
{"downloadurl":"http://192.168.1.100:8080/xxx.apk","Version":"2","desc":"下載安裝送大禮包"}//key和value
把以上代碼寫在新建文件info.json並放在tomcat服務器裏提供給別人下載
課3
演示更新功能
更新的流程圖(步驟)
1、請求服務器下載json文件,並解析json數據
2、判斷版本號是否一致
1、版本相同:進入主界面
2、版本不同:彈出對話框
1、更新:提供下載鏈接:讀取數據進行升級後進入主界面
2、不更新:進入主頁面
權限:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.phonesafeguard"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.phonesafeguard.SplashActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.itheima.phonesafeguard.MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"></activity>
</application>
</manifest>
佈局:activity_splash.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#88000000" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:layout_centerInParent="true"
android:id="@+id/image_View"
/>
<ProgressBar
android:id="@+id/pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/image_View"
/>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="版本號"/>
</RelativeLayout>
SplashActivity.java
public class SplashActivity extends Activity {
protected String downloadurl;
protected String desc;
protected int version;
//演示xUtils
//這種方式就可以直接使用image_view去讀取網絡路徑的圖片
@ViewInject(R.id.image_View)
private ImageView image_view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//設置沒有標題,以下兩行代碼順序注意
requestWindowFeature(Window.FEATURE_NO_TITLE);//設置歡迎界面
setContentView(R.layout.activity_splash);
// JSONObject json = new JSONObject();
/**
* 獲取包的管理者
* <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.phonesafeguard"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto" >
*/
PackageManager pm = getPackageManager();
try {
//獲取到安裝包的基本信息
// PackageInfo packageinfo = pm.getPackageInfo("com.itheima.phonesafeguard", 0);
//可以寫活
PackageInfo packageinfo = pm.getPackageInfo(getPackageName(), 0);
//獲取版本號
int versionCode = packageinfo.versionCode;
System.out.println("版本號"+versionCode);
//解析服務器下載下來的json數據,解析版本號
//加上聯網權限
checkVersion();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
private void checkVersion() {
//這也是一種獲取線程的方法:開啓線程池:比我們用的一般開啓線程的方法優點多
// ExecutorService Executorpool = Executors.newFixedThreadPool(nThreads);
//寫子線程來聯網
new Thread(){
public void run(){
//寫業務邏輯
try {
//初始化url連接
URL url = new URL("http://192.168.1.100:8080/info.json");
//獲取聯網的conn
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//設置請求方法
conn.setRequestMethod("GET");
//設置請求超時時間
conn.setConnectTimeout(5000);//5秒
//獲取服務器返回的code編碼
int code = conn.getResponseCode();
//如果code等於200的話,成功
if(code == 200){
//獲取服務器的流數據
InputStream is = conn.getInputStream();
//獲取服務器返回的數據
String json = StreamUtils.readStream(is);
//解析從服務器獲取的數據
JSONObject obj = new JSONObject(json);
//解析json
/*
* {"downloadurl":"http://192.168.1.100:8080/xxx.apk","Version":"2","desc":"下載安裝送大禮包"}
*key是唯一的
*/
//獲取到下載到的url地址
downloadurl = obj.getString("downloadurl");
//獲取到描述信息
desc = obj.getString("desc");
//獲取版本信息
version = obj.getInt("version");
//打印測試
System.out.println("downloadurl--->"+downloadurl);
System.out.println("desc--->"+desc);
System.out.println("version--->"+version);
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
}
課4
google-gson下載
使用gson
在xutils裏配合使用,效率很高
完成課3的邏輯
SplashActivity.java
public class SplashActivity extends Activity {
//展示對話框
protected static final int SHOW_DIALOG = 0;
//進入主界面
protected static final int ENTERMAIN = 1;
protected String downloadurl;
protected String desc;
protected int version;
//演示xUtils
//這種方式就可以直接使用image_view去讀取網絡路徑的圖片
@ViewInject(R.id.image_View)
private ImageView image_view;
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
//做彈框操作
switch(msg.what){
case SHOW_DIALOG:
AlertDialog.Builder builder = new Builder(SplashActivity.this);
builder.setTitle("有新版本");
builder.setMessage("穩定性很好");
builder.setPositiveButton("更新", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.show();
break;
case ENTERMAIN:
mainUI();
break;
}
};
};
private int versionCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//設置沒有標題,以下兩行代碼順序注意
requestWindowFeature(Window.FEATURE_NO_TITLE);//設置歡迎界面
setContentView(R.layout.activity_splash);
// JSONObject json = new JSONObject();
/**
* 獲取包的管理者
* <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.phonesafeguard"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto" >
*/
PackageManager pm = getPackageManager();
try {
//獲取到安裝包的基本信息
// PackageInfo packageinfo = pm.getPackageInfo("com.itheima.phonesafeguard", 0);
//可以寫活
PackageInfo packageinfo = pm.getPackageInfo(getPackageName(), 0);
versionCode = packageinfo.versionCode;
System.out.println("版本號"+versionCode);
//解析服務器下載下來的json數據,解析版本號
//加上聯網權限
checkVersion();//不推薦!實際中效率會很低,我們不可能手動去導出海量的json數據
//Xtils的解析json方法
// checkVersion2();//效率高,但黑馬課程大綱不做要求
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
//使用xUtil來獲取版本號
private void checkVersion2(){
HttpUtils httpUtils = new HttpUtils();
//這裏的URL最好不要寫死,因爲我們要測試
httpUtils.send(HttpMethod.GET, HMAPI.url, new RequestCallBack<String>() {
@Override
public void onFailure(HttpException arg0, String arg1) {
}
@Override
public void onSuccess(ResponseInfo<String> arg0) {
//自動解析json
System.out.println("result:"+arg0);
/**
* google-gson下載
使用gson
在xutils裏配合使用,效率很高
*/
// Gson gson = new Gson();
// mobileInfo info = gson.fromJson(arg0.result,mobileInfo.class);
// System.out.println("result:"+arg0);
}
});
}
private void checkVersion() {
//這也是一種獲取線程的方法:開啓線程池:比我們用的一般開啓線程的方法優點多
// ExecutorService Executorpool = Executors.newFixedThreadPool(nThreads);
//寫子線程來聯網
new Thread(){
// Message msg = new Message();
Message msg = Message.obtain();//從池中拿消息
public void run(){
//寫業務邏輯
try {
//初始化url連接
URL url = new URL(HMAPI.url);
//獲取聯網的conn
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//設置請求方法
conn.setRequestMethod("GET");
//設置請求超時時間
conn.setConnectTimeout(5000);//5秒
//獲取服務器返回的code編碼
int code = conn.getResponseCode();
//如果code等於200的話,成功
if(code == 200){
//獲取服務器的流數據
InputStream is = conn.getInputStream();
//獲取服務器返回的數據
String json = StreamUtils.readStream(is);
if(!TextUtils.isEmpty(json)){
//解析從服務器獲取的數據
JSONObject obj = new JSONObject(json);
//解析json
/*
* {"downloadurl":"http://192.168.1.100:8080/xxx.apk","Version":"2","desc":"下載安裝送大禮包"}
*key是唯一的
*/
//獲取到下載到的url地址
downloadurl = obj.getString("downloadurl");
//獲取到描述信息
desc = obj.getString("desc");
//獲取版本信息
version = obj.getInt("version");
System.out.println("-----------------------------------");
//打印測試
System.out.println("downloadurl--->"+downloadurl);
System.out.println("desc--->"+desc);
System.out.println("version--->"+version);
//判斷本地的版本號和服務器返回的版本號做對比
if(version == versionCode){
//跳刀
mainUI();
System.out.println("版本號相同");
msg.what = ENTERMAIN;
handler.sendMessage(msg);
}else{
System.out.println("版本號不同");
msg.what = SHOW_DIALOG;
handler.sendMessage(msg);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
protected void mainUI() {
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
finish();
};
}
mobileInfo.java
package com.itheima.phonesafeguard.bean;
public class mobileInfo {
private String downloadurl;
private int version;
private String desc;
public String getDownloadurl() {
return downloadurl;
}
public void setDownloadurl(String downloadurl) {
this.downloadurl = downloadurl;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "mobileInfo [downloadurl=" + downloadurl + ", version="
+ version + ", desc=" + desc + "]";
}
}
HMAPI.java
package com.itheima.Utils;
public class HMAPI {
//如果不需要再改的東西儘量封裝起來,爲以後大量的信息修改提供查看便捷
public static String BASEURL = "http://192.168.1.100:8080/";
public static String url = BASEURL+"info.json";
}
StreamUtils.java
public class StreamUtils {
public static String readStream(InputStream is){
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
return new String(baos.toByteArray());
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
課5
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@drawable/ic_launcher"
android:gravity="center"
android:text="主界面" />
<!--android:ellipsize="marquee" 表示可以讓textview移動 -->
<com.itheima.mobile47.view.CustomTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="marquee"
android:focusableInTouchMode="true"
android:textColor="#E2DED8"
android:text="歡迎使用我的手機衛士,只要您使用了我爲您親身定製了的手機衛士,一定會感覺自己萌萌噠噠噠噠噠噠!!!"
/>
<GridView
android:id="@+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:verticalSpacing="10dp"
android:numColumns="3" >
</GridView>
</LinearLayout>
itemmaingridview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_launcher" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="手機殺毒"
/>
</LinearLayout>
CustomTextView.java
package com.itheima.phonesafeguard.view;
public class CustomTextView extends TextView {
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomTextView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
@ExportedProperty(category = "focus")
public boolean isFocused() {
// TODO Auto-generated method stub
return true;
}
}
MainActivity.java
package com.itheima.phonesafeguard;
public class MainActivity extends Activity {
private String[] names = {"手機防盜","通訊衛視","軟件管家","進程管理","流量統計","手機殺毒","緩存清理","高級工具","設置中心"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
//初始化界面
initView();
}
private void initView() {
GridView grid_view = (GridView) findViewById(R.id.grid_view);
MainAdapter adapter = new MainAdapter();
grid_view.setAdapter(adapter);
}
//適配器
private class MainAdapter extends BaseAdapter{
@Override
public int getCount() {
// TODO Auto-generated method stub
return names.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return names[position];
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(MainActivity.this, R.layout.item_main_gridview, null);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
tv_name.setText(names[position]);
return view;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
SplashActivity.java
package com.itheima.phonesafeguard;
public class SplashActivity extends Activity {
//展示對話框
protected static final int SHOW_DIALOG = 0;
//進入主界面
protected static final int ENTERMAIN = 1;
protected String downloadurl;
protected String desc;
protected int version;
//演示xUtils
//這種方式就可以直接使用image_view去讀取網絡路徑的圖片
@ViewInject(R.id.image_View)
private ImageView image_view;
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
//做彈框操作
switch(msg.what){
case SHOW_DIALOG:
AlertDialog.Builder builder = new Builder(SplashActivity.this);
builder.setTitle("有新版本");
builder.setMessage("穩定性很好");
builder.setPositiveButton("更新", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// mainUI();
//下載apk方法
downloadapk();
}
});
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mainUI();
}
});
builder.show();
break;
case ENTERMAIN:
mainUI();
break;
}
};
};
private int versionCode;
private void downloadapk() {
HttpUtils httpUtils = new HttpUtils();
/**
* 下載數據
* 第一個參數是要下載的URL地址
* 第二個參數表示下載之後放置的位置
*/
httpUtils.download(downloadurl, "/mnt/sdcard/temp.apk", new RequestCallBack<File>() {
@Override
public void onFailure(HttpException arg0, String arg1) {
Toast.makeText(SplashActivity.this, "下載失敗", 0).show();
mainUI();
}
@Override
public void onSuccess(ResponseInfo<File> arg0) {
Toast.makeText(SplashActivity.this, "下載成功", 0).show();
System.out.println("下載成功");
//加入安裝的代碼
// 啓動安裝的隱式意圖
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setDataAndType(Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), "temp.apk")),
"application/vnd.android.package-archive");
startActivity(intent);
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//設置沒有標題,以下兩行代碼順序注意
requestWindowFeature(Window.FEATURE_NO_TITLE);//設置歡迎界面
setContentView(R.layout.activity_splash);
ViewUtils.inject(this);
// JSONObject json = new JSONObject();
/**
* 獲取包的管理者
* <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itheima.phonesafeguard"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto" >
*/
PackageManager pm = getPackageManager();
try {
//獲取到安裝包的基本信息
// PackageInfo packageinfo = pm.getPackageInfo("com.itheima.phonesafeguard", 0);
//可以寫活
PackageInfo packageinfo = pm.getPackageInfo(getPackageName(), 0);
versionCode = packageinfo.versionCode;
System.out.println("版本號"+versionCode);
//解析服務器下載下來的json數據,解析版本號
//加上聯網權限
checkVersion();//不推薦!實際中效率會很低,我們不可能手動去導出海量的json數據
//Xtils的解析json方法
// checkVersion2();//效率高,但黑馬課程大綱不做要求
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
//使用xUtil來獲取版本號
private void checkVersion2(){
HttpUtils httpUtils = new HttpUtils();
//這裏的URL最好不要寫死,因爲我們要測試
httpUtils.send(HttpMethod.GET, HMAPI.url, new RequestCallBack<String>() {
@Override
public void onFailure(HttpException arg0, String arg1) {
}
@Override
public void onSuccess(ResponseInfo<String> arg0) {
//自動解析json
System.out.println("result:"+arg0);
/**
* google-gson下載
使用gson
在xutils裏配合使用,效率很高
*/
// Gson gson = new Gson();
// mobileInfo info = gson.fromJson(arg0.result,mobileInfo.class);
// System.out.println("result:"+arg0);
}
});
}
private void checkVersion() {
//這也是一種獲取線程的方法:開啓線程池:比我們用的一般開啓線程的方法優點多
// ExecutorService Executorpool = Executors.newFixedThreadPool(nThreads);
//寫子線程來聯網
new Thread(){
// Message msg = new Message();
Message msg = Message.obtain();//從池中拿消息
public void run(){
//寫業務邏輯
try {
//初始化url連接
URL url = new URL(HMAPI.url);
//獲取聯網的conn
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//設置請求方法
conn.setRequestMethod("GET");
//設置請求超時時間
conn.setConnectTimeout(5000);//5秒
//獲取服務器返回的code編碼
int code = conn.getResponseCode();
//如果code等於200的話,成功
if(code == 200){
//獲取服務器的流數據
InputStream is = conn.getInputStream();
//獲取服務器返回的數據
String json = StreamUtils.readStream(is);
if(!TextUtils.isEmpty(json)){
//解析從服務器獲取的數據
JSONObject obj = new JSONObject(json);
//解析json
/*
* {"downloadurl":"http://192.168.1.100:8080/xxx.apk","Version":"2","desc":"下載安裝送大禮包"}
*key是唯一的
*/
//獲取到下載到的url地址
downloadurl = obj.getString("downloadurl");
//獲取到描述信息
desc = obj.getString("desc");
//獲取版本信息
version = obj.getInt("version");
System.out.println("-----------------------------------");
//打印測試
System.out.println("downloadurl--->"+downloadurl);
System.out.println("desc--->"+desc);
System.out.println("version--->"+version);
//判斷本地的版本號和服務器返回的版本號做對比
if(version == versionCode){
//調到
mainUI();
System.out.println("版本號相同");
msg.what = ENTERMAIN;
handler.sendMessage(msg);
}else{
System.out.println("版本號不同");
msg.what = SHOW_DIALOG;
handler.sendMessage(msg);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
protected void mainUI() {
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
finish();
};
}
課6
準備給手機衛士的開始界面嵌入訊飛的語音識別代碼
首先要導入包 瞭解老師的語音識別代碼例子:記住複製代碼到這裏來 把代碼嵌入到手機衛士工程中 導入金山的按鈕圖片到drawable-hdpi中 bitmap:只jpg,png等等,即只是單純的圖片 drawable:還包括所有的資源
這節課主要是修改按鈕點擊風格。 在drawable目錄下新建selector.xml 在裏面通過item去設置點擊還有其他動作的資源反應 並一次生成9個xml 每個xml所對應的圖片資源要自定義好 然後在MainActivity裏導入這些資源來使用icon[] 在MyAdapter裏的getView方法裏調用 然後修改界面邊幅
selector_1.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true"
android:drawable="@drawable/main_start_item_manager_icon_pressed" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="@drawable/main_start_item_manager_icon_pressed" /> <!-- focused -->
<item android:drawable="@drawable/main_start_item_manager_icon" /> <!-- default -->
</selector>
MainActivity.java
private int[] icons = { R.drawable.selector_1, R.drawable.selector_2,
R.drawable.selector_3, R.drawable.selector_4,
R.drawable.selector_5, R.drawable.selector_6,
R.drawable.selector_7, R.drawable.selector_8,
R.drawable.selector_9, };
private void initView() {
GridView grid_view = (GridView) findViewById(R.id.grid_view);
grid_view.setOnItemClickListener(this);
MainAdapter adapter = new MainAdapter();
grid_view.setAdapter(adapter);
}
private class MainAdapter extends BaseAdapter {
@Override
public int getCount() {
// TODO Auto-generated method stub
return names.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return names[position];
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(MainActivity.this,
R.layout.item_main_gridview, null);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
tv_name.setText(names[position]);
ImageView iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
iv_icon.setImageResource(icons[position]);
return view;
}
}
繼續實現手機防盜功能
給按鈕添加點擊事件(GridView的點擊事件)
public class MainActivity extends Activity implements OnItemClickListener { 點擊功能後彈出一個對話框
MainActivity.java
/**
* gridview的點擊事件
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
switch (position) {
case 0:
//判斷當前是否設置過防盜的密碼
if(TextUtils.isEmpty(isPwd())){
//說明沒有設置
setSetupPwd();
}else{
//說明設置了密碼
setEnterUpPwd();
}
break;
default:
break;
}
}
/**
* 已經設置過密碼
*/
private void setEnterUpPwd() {
AlertDialog.Builder builder = new Builder(MainActivity.this);
View dialog_view = View.inflate(MainActivity.this, R.layout.dialog_enter_pwd_main, null);
et_pwd = (EditText) dialog_view.findViewById(R.id.et_pwd);
Button bt_ok = (Button) dialog_view.findViewById(R.id.bt_ok);
Button bt_cancel = (Button) dialog_view.findViewById(R.id.bt_cancel);
bt_ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//獲取密碼裏面的值。然後判斷2次輸入的值是否一樣
String et_password = et_pwd.getText().toString().trim();
if(TextUtils.isEmpty(et_password) ){
return ;
}
String pwd = sp.getString("pwd", "");
//如果sp裏面緩存的密碼和輸入的密碼一樣的話。那麼就進入防盜的引導界面
if(et_password.equals(pwd)){
Intent intent = new Intent(MainActivity.this,GuideActivity1.class);
startActivity(intent);
finish();
}else{
Toast.makeText(MainActivity.this, "2次密碼不一致", 0).show();
}
}
});
bt_cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
builder.setView(dialog_view);
dialog = builder.show();
}
新建dialogsetuppwd_main.xml佈局新界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#88ff0000"
android:gravity="center"
android:text="請輸入防盜密碼"
android:textColor="#000"
android:textSize="24sp" />
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入密碼"
android:inputType="phone"
android:password="true" />
<EditText
android:id="@+id/et_queren"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請確認密碼"
android:inputType="phone"
android:password="true"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_ok"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_selector"
android:text="確定" />
<Button
android:id="@+id/bt_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_selector"
android:text="取消" />
</LinearLayout>
</LinearLayout>
該界面是設置防盜密碼
給確定和取消按鈕添加選擇器(選擇器放在drawable)
MainActivity.java
/**
* gridview的點擊事件
*/
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
switch (position) {
case 0:
//判斷當前是否設置過防盜的密碼
if(TextUtils.isEmpty(isPwd())){
//說明沒有設置
setSetupPwd();
}else{
//說明設置了密碼
setEnterUpPwd();
}
break;
default:
break;
}
}
private String isPwd() {
String str = sp.getString("pwd", "");
return str;
}
btn_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true"
android:drawable="@drawable/btn_green_pressed" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="@drawable/btn_green_pressed" /> <!-- focused -->
<item android:drawable="@drawable/btn_green_normal" /> <!-- default -->
</selector>
課7
給確定和取消按鈕添加功能
如果輸入正確,就把密碼存在緩存裏,使用sharedPreference存儲再dialog.dismiss();
MainActivity.java
/**
* 第一次進來的時候。如果沒有設置密碼。請設置密碼界面
*/
private void setSetupPwd() {
AlertDialog.Builder builder = new Builder(MainActivity.this);
View dialog_view = View.inflate(MainActivity.this, R.layout.dialog_setup_pwd_main, null);
et_pwd = (EditText) dialog_view.findViewById(R.id.et_pwd);
et_queren = (EditText) dialog_view.findViewById(R.id.et_queren);
Button bt_ok = (Button) dialog_view.findViewById(R.id.bt_ok);
Button bt_cancel = (Button) dialog_view.findViewById(R.id.bt_cancel);
bt_ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//獲取密碼裏面的值。然後判斷2次輸入的值是否一樣
String et_password = et_pwd.getText().toString().trim();
String et_querenPassword = et_queren.getText().toString().trim();
if(TextUtils.isEmpty(et_password) ){
return ;
}
if(TextUtils.isEmpty(et_querenPassword)){
return;
}
if(et_password.equals(et_querenPassword)){
Editor edit = sp.edit();
edit.putString("pwd", et_password);
edit.commit();
dialog.dismiss();
}else{
Toast.makeText(MainActivity.this, "2次密碼不一致", 0).show();
}
}
});
bt_cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
builder.setView(dialog_view);
dialog = builder.show();
}
取消鍵就dialog.dismiss();//關閉對話框
在存儲了密碼後就判斷sp裏面是否有值,即每次打開手機防盜功能時都檢查sp裏面是否有值,沒有就彈出設置密碼框(執行setSetUpPwd方法):進入dialogenterpwdmain.xml,有就彈出進入到另一個界面(執行setEnterUpPwd方法):dialogsetuppwdmain.xml該界面會判斷sp裏的密碼和用戶輸入的密碼是否一樣,一樣就進入新的界面(引導界面):GuideActivity1(新建+配置清單文件)
dialogenterpwd_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#88ff0000"
android:gravity="center"
android:text="請輸入防盜密碼"
android:textColor="#000"
android:textSize="24sp" />
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入密碼"
android:inputType="phone"
android:password="true"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_ok"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="確定"
android:background="@drawable/btn_selector"/>
<Button
android:id="@+id/bt_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="取消"
android:background="@drawable/btn_selector"/>
</LinearLayout>
</LinearLayout>
MainActivity.java
/**
* 已經設置過密碼
*/
private void setEnterUpPwd() {
AlertDialog.Builder builder = new Builder(MainActivity.this);
View dialog_view = View.inflate(MainActivity.this, R.layout.dialog_enter_pwd_main, null);
et_pwd = (EditText) dialog_view.findViewById(R.id.et_pwd);
Button bt_ok = (Button) dialog_view.findViewById(R.id.bt_ok);
Button bt_cancel = (Button) dialog_view.findViewById(R.id.bt_cancel);
bt_ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//獲取密碼裏面的值。然後判斷2次輸入的值是否一樣
String et_password = et_pwd.getText().toString().trim();
if(TextUtils.isEmpty(et_password) ){
return ;
}
String pwd = sp.getString("pwd", "");
//如果sp裏面緩存的密碼和輸入的密碼一樣的話。那麼就進入防盜的引導界面
if(et_password.equals(pwd)){
Intent intent = new Intent(MainActivity.this,GuideActivity1.class);
startActivity(intent);
finish();
}else{
Toast.makeText(MainActivity.this, "2次密碼不一致", 0).show();
}
}
});
bt_cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
builder.setView(dialog_view);
dialog = builder.show();
}
繼續設置引導界面(有四個,新建4個引導界面:GuideActivity1、GuideActivity2、GuideActivity3、GuideActivity4) 配清單文件
<application
android:allowBackup="true"
android:icon="@drawable/main_icon"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.itheima.mobile47.SplashActivity"
android:label="@string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.itheima.mobile47.MainActivity"
android:screenOrientation="portrait" >
</activity>
<activity
android:name="com.itheima.mobile47.GuideActivity1"
android:screenOrientation="portrait" >
</activity>
<activity
android:name="com.itheima.mobile47.GuideActivity2"
android:screenOrientation="portrait" >
</activity>
<activity
android:name="com.itheima.mobile47.GuideActivity3"
android:screenOrientation="portrait" >
</activity>
<activity
android:name="com.itheima.mobile47.GuideActivity4"
android:screenOrientation="portrait" >
</activity>
</application>
修改小bug,手機返回鍵點擊會使界面一直停留在開機界面
取消返回鍵:builder.setCancelable(false);//但這樣用戶體驗不好,所以取消這種方法
我們採用另外一種方式,使用監聽器來監聽返回鍵,但點擊返回鍵也可以跳到主界面(bug修好) 把開機的setMessage改成json傳來的描述信息,這樣可以不讓軟件寫死
MainActivity.class
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case SHOW_DIALOG:
AlertDialog.Builder builder = new Builder(SplashActivity.this);
builder.setTitle("有新版本");
builder.setMessage(desc);
//屏蔽後退按鈕
// builder.setCancelable(false);
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
mainUI();
}
});
技巧總結
技巧回顧
如何使用提示框來彈出已經提前準備好了的佈局xml文件 這是已經準備好的xml文件:dialogsetuppwd_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#88007573"
android:gravity="center"
android:text="請輸入防盜密碼"
android:textColor="#000"
android:textSize="24sp" />
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入密碼"
android:inputType="phone"
android:password="true" />
<EditText
android:id="@+id/et_queren"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請確認密碼"
android:inputType="phone"
android:password="true"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_ok"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_selector"
android:text="確定" />
<Button
android:id="@+id/bt_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_selector"
android:text="取消" />
</LinearLayout>
</LinearLayout>
MainActivity.class
/**
* 第一次進來的時候。如果沒有設置密碼。請設置密碼界面
*/
private void setSetupPwd() {
AlertDialog.Builder builder = new Builder(MainActivity.this);
View dialog_view = View.inflate(MainActivity.this, R.layout.dialog_setup_pwd_main, null);
//在這裏爲佈局文件裏的控件添加邏輯
builder.setView(dialog_view);
dialog = builder.show();
}
style風格的使用
activitylistview_contact.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
style="@style/textview_title_style"
android:gravity="center"
android:text="選擇聯繫人" />
<include layout="@layout/list_view" />
</LinearLayout>
styles.xml
<!-- <TextView -->
<!-- android:layout_width="match_parent" -->
<!-- android:layout_height="40dp" -->
<!-- android:background="#4400ff00" -->
<!-- android:text="歡迎使用手機防盜" -->
<!-- android:textSize="24sp" /> -->
<style name="textview_title_style">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">40dp</item>
<item name="android:background">#4400ff00</item>
<item name="android:textSize">24sp</item>
</style>
資料下載