手机卫士-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>
资料下载