Splash界面
splash: 溅,洒
展现产品的logo提升产品的知名度 初始化操作(创建数据库,读取配置文件)
连接服务器检查软件授权 连接服务器检查软件的更新
自动更新的前提
包名一致 签名一致
状态选择器
整体取消掉标题栏:在清单文件中加一修改主题
android:theme=”@android:style/Theme.Light.NoTitleBar”
PackageManager:获取各种包的信息(版本、应用程序图标、包信息等)
开源项目框架:
xUtils-2.6.8.jar 断点下载
使用:
1
2
3
4
5
6
7
8
9
10
11
12
|
HttpUtils
httputils= new
HttpUtils();
httputils.download(url,target,autoResume,callback);
new
RequestCallBack<file>(){
重写onSuccess();
重写onFailure();
重写onload();
}
</file>
|
开源项目断点下载xUtils耗时操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
HttpUtils
http= new
HttpUtils();
final
File file= new
File(Environment.getExternalStorageDirectory(), "xxx.apk" );
http.download(data.downLoadUrl,
file.getAbsolutePath(), true ,
new
RequestCallBack<file>(){
@Override
public
void
onFailure(HttpException arg0, String arg1) {
}
@Override
public
void
onSuccess(ResponseInfo arg0) {
ToastUtils.show(SplashActivity. this ,
"下载成功" );
Intent
intent= new
Intent();
intent.setAction( "android.intent.action.VIEW" );
intent.addCategory( "android.intent.category.DEFAULT" );
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive" );
startActivity(intent);
}});
</file>
|
<h3 id="下载替换安装只要调用
系统的应用就行模板代码">下载替换安装只要调用系统的应用就行:(模板代码)
1
2
3
4
5
|
Itent
intent= new
Intent();
intent.setAction( "android.intent.action.VIEW" );
intent.addCategory( "android.intent.category.DEFAULT" );
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive" );
startActivity(intent);
|
市面上常用界面-九宫格
状态选择器:
就是在res目录下建立一个drawable文件中定义一个xml文件,设置属性background时引用这个xml文件就行。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<!--?xml
version= "1.0"
encoding= "utf-8" ?-->
<item
android:drawable= "@android:color/darker_gray"
android:state_pressed= "true" >
<item
android:drawable= "@android:color/darker_gray"
android:state_focused= "true" >
<item
android:drawable= "@android:color/transparent" >
</item>
</item>
</item>
</selector>
|
按住图标显示不一样的图片,新建一个tupian.xml文件,引用图标时R.drawable.tupian.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<!--?xml
version= "1.0"
encoding= "utf-8" ?-->
<item
android:drawable= "@drawable/app_pressed"
android:state_pressed= "true" >
<item
android:drawable= "@drawable/app_focused"
android:state_focused= "true" >
<item
android:drawable= "@drawable/app" >
</item>
</item>
</item>
</selector>
|
走马灯效果按钮
Button可实现,当点击按钮的时候滚动起来
设置属性
1
2
3
|
android:focusableInTouchMode= "true"
android:ellipsize= "marquee"
android:text= "显示的内容"
|
TextView也可以实现滚动走马灯:需要自定义TextView,实现里面的所有构造函数并重写isFocused()直接返回true
1
2
3
4
5
|
@Override
@ExportedProperty (category
= "focus" )
public
boolean
isFocused() {
return
true ;
}
|
并设置下面几个属性
1
2
|
<com.cca.mobilephone.ui.focusedtextview
android:ellipsize= "marquee"
android:focusableintouchmode= "true"
android:layout_height= "wrap_content"
android:layout_width= "match_parent"
android:singleline= "true"
android:text= "希望我所认识的亲戚朋友远离病痛,远离饥饿,走上富康的道路,过上幸福的的生活!" >
</com.cca.mobilephone.ui.focusedtextview>
|
这样textview跑马灯效果就可以跑起来了
设置一条线可以使用View
自定义组合控件:textView+checkBox 下面还有一条分割线
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
class
SettingCheckView extends
LinearLayout {
public
SettingCheckView(Context context, AttributeSet attrs) {
super (context,
attrs);
initial(context);
TextView
tv_title=(TextView) findViewById(R.id.tv_ui_setting);
tv_title.setText(bigtitle);
}
public
SettingCheckView(Context context) {
super (context);
initial(context);
}
private
void
initial(Context context) {
this .setOrientation(LinearLayout.VERTICAL);
this .addView(View.inflate(context,
R.layout.ui_setting_view, null ));
}
}
|
布局文件:
1
2
3
4
5
6
7
8
9
10
|
<!--?xml
version= "1.0"
encoding= "utf-8" ?-->
<relativelayout
android:background= "@drawable/background"
android:id= "@+id/rl_set_update"
android:layout_gravity= "center_vertical"
android:layout_height= "50dp"
android:layout_width= "match_parent"
xmlns:android= "http://schemas.android.com/apk/res/android" >
<textview
android:id= "@+id/tv_ui_setting"
android:layout_centervertical= "true"
android:layout_height= "wrap_content"
android:layout_marginleft= "10dp"
android:layout_width= "match_parent"
android:text= "开启自动更新"
android:textsize= "20sp" >
<checkbox
android:clickable= "false"
android:focusable= "false"
android:id= "@+id/cb_set_update"
android:layout_alignparentright= "true"
android:layout_centervertical= "true"
android:layout_height= "wrap_content"
android:layout_marginright= "20dp"
android:layout_width= "wrap_content" >
<view
android:background= "#88000000"
android:layout_height= "0.1dp"
android:layout_margin= "2dp"
android:layout_width= "match_parent" >
</view></checkbox></textview></relativelayout>
|
使用时:
1
2
|
<com.cca.mobilephone.ui.settingcheckview
android:layout_height= "wrap_content"
android:layout_width= "match_parent"
mobilephone:bigtitle= "我是功能2" >
</com.cca.mobilephone.ui.settingcheckview>
|
自定义属性:
先声明属性命名空间
在values定义一个attrs.xml文件,在里面声明功能
1
2
3
4
5
6
7
8
9
10
11
|
<!--?xml
version= "1.0"
encoding= "utf-8" ?-->
<resources>
<declare-styleable
name= "SettingCheckView" >
</attr></declare-styleable>
<declare-styleable
name= "SettingCheckView" >
</attr></declare-styleable>
</resources>
|
做到这里就可以使用自定义组合控件了,功能可以设置文本内容,想增加其他的属性,在attrs中定义出来就可以使用了。
自定义对话框:
1
2
3
4
|
AlertDialog.Builder
builder= new
Builder(context);
View
dialogview=View.inflate(context, R.layout.show_setup_dialog, null );
builder.setView(view);
builder.show();
|
//高低版本默认的背景色和字体颜色不一样、使高低版本保持一致的样式需
设置其背景色、文本字体色
1
2
3
4
5
|
AlertDialog.Builder
builder= new
Builder(MainActivity. this );
View
dialogview=View.inflate(context, R.layout.show_setup_dialog, null );
AlertDialog
dialog=builder.create();
dialog.setView(dialogview, 0 , 0 , 0 , 0 );
dialog.show();
|
show_setup_dialog的xml布局文件如下:
1
2
3
4
5
6
|
<!--?xml
version= "1.0"
encoding= "utf-8" ?-->
<textview
android:background= "#BFFF01"
android:gravity= "center"
android:layout_height= "wrap_content"
android:layout_width= "match_parent"
android:text= "设置密码"
android:textsize= "30dp" >
<edittext
android:gravity= "center_horizontal"
android:hint= "请输入密码"
android:inputtype= "textPassword"
android:layout_height= "wrap_content"
android:layout_marginleft= "5dp"
android:layout_marginright= "5dp"
android:layout_width= "300dp" >
<edittext
android:gravity= "center_horizontal"
android:hint= "请确定密码"
android:inputtype= "textPassword"
android:layout_height= "wrap_content"
android:layout_marginleft= "5dp"
android:layout_marginright= "5dp"
android:layout_width= "300dp" >
<linearlayout
android:layout_height= "wrap_content"
android:layout_width= "300dp" ><button
android:background= "@drawable/btn_background"
android:layout_height= "wrap_content"
android:layout_marginright= "5dp"
android:layout_weight= "1"
android:layout_width= "0dp"
android:text= "取消" ></button><button
android:background= "@drawable/btn_background"
android:layout_height= "wrap_content"
android:layout_marginleft= "5dp"
android:layout_weight= "1"
android:layout_width= "0dp"
android:text= "确定" ></button></linearlayout></edittext></edittext></textview></linearlayout>
|
自定义背景选择器:btn_background.xml(要放在drawable文件下)
1
2
3
4
5
6
7
8
9
10
|
<!--?xml
version= "1.0"
encoding= "utf-8" ?-->
<item
android:drawable= "@android:color/holo_blue_light"
android:state_pressed= "true" >
<item
android:drawable= "@android:color/holo_blue_light"
android:state_focused= "true" >
<item
android:drawable= "@android:color/transparent" >
</item></item></item>
</selector>
|
当有很多个界面有相同的方法,相同的布局时,都要存储数据时,可定义一个父类让其他的类来继承它
动画的切换效果:
1
2
|
overridePendingTransition(R.anim.trans_next_in,
R.anim.trans_next_out);
|
在res目录下建立一个anim文件夹:创建两个xml:trans_next_in.xml和trans_next_out.xml如下
1
2
3
4
5
6
7
8
|
<!--?xml
version= "1.0"
encoding= "utf-8" ?-->
</translate>
<!--?xml
version= "1.0"
encoding= "utf-8" ?-->
</translate>
|
手势识别器
1、先声明一个手势识别器
1
|
private
GestureDetector mGestureDetector;
|
2、初始化一个手势识别器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
mGestureDetector= new
GestureDetector(getApplicationContext(), new
GestureDetector.SimpleOnGestureListener(){
@Override
public
boolean
onFling(MotionEvent e1, MotionEvent e2,
float
velocityX, float
velocityY) {
/**
*
e1、手指触摸屏幕的一瞬间
*
e2、手指离开屏幕的一瞬间
*
velocityX、velocityY:水平方向和竖直方向的速度
*
*/
if ((e1.getRawX()-e2.getRawX())> 150 ){
showNext();
overridePendingTransition(R.anim.trans_next_in,
R.anim.trans_next_out);
return
true ;
}
if ((e2.getRawX()-e1.getRawX())> 150 ){
showPre();
overridePendingTransition(R.anim.trans_pre_in,
R.anim.trans_pre_out);
return
true ;
}
return
super .onFling(e1,
e2, velocityX, velocityY);
}
});
|
3、第三步、使用户识别手势器的动作
1
2
3
4
5
6
|
@Override
public
boolean
onTouchEvent(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return
super .onTouchEvent(event);
}
|
绑定手机卡、获取手机序列号,一个手机号对应一个序列号
1
2
3
4
|
private
TelephonyManager tm=(TelephonyManager) this .getSystemService(Context.TELEPHONY_SERVICE);
String
sim=tm.getSimSerialNumber();
|
电话联系人
data/data/com.android.providers.contacts.database.contacts2.db
对应三张表:
查找联系人工具类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
public
class
ContactsInfoUtils {
public
static
List<contactsinfo> getContactsInfo(Context context){
List<contactsinfo>
infocontacts= new
ArrayList<contactsinfo>();
ContentResolver
resolver=context.getContentResolver();
Cursor
cursor=resolver.query(uri, new
String[]{ "contact_id" },
null ,
null ,
null );
while (cursor.moveToNext()){
String
id=cursor.getString( 0 );
System.out.println( "id" +id);
ContactsInfo
infos= new
ContactsInfoUtils(). new
ContactsInfo();
Cursor
datacursor=resolver.query(dataUri, new
String[]{ "data1" },
"raw_contact_id=?" ,
null ,
null );
while (datacursor.moveToNext()){
String
data1=datacursor.getString( 0 );
String
mimetype=datacursor.getString( 1 );
if ( "vnd.android.cursor.item/name" .equals(mimetype)){
infos.name=data1;
} else
if ( "vnd.android.cursor.item/phone_v2" .equals(mimetype)){
infos.phone=data1;
} else
if ( "vnd.android.cursor.item/email_v2" .equals(mimetype)){
infos.email=data1;
}
}
infocontacts.add(infos);
}
return
infocontacts;
}
public
class
ContactsInfo{
public
String name;
public
String email;
public
String phone;
}
}
</contactsinfo></contactsinfo></contactsinfo>
|
<h2 id="密码
加密md5-单向加密不可逆原文密文">密码加密:md5 单向加密,不可逆原文–>密文
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
static
String encode(String text){
try
{
MessageDigest
digest=MessageDigest.getInstance( "md5" );
String
password= "234" ;
byte []
result=digest.digest(password.getBytes());
StringBuffer
sb= new
StringBuffer();
for ( byte
b:result){
String
hex=Integer.toHexString(b& 0xff )+ 2 ;
if (hex.length()== 1 ){
sb.append( "0" );
}
sb.append(hex);
}
return
sb.toString();
}
catch
(NoSuchAlgorithmException e) {
e.printStackTrace();
return
"" ;
}
}
|
播放报警音乐:便捷方式:src下新建目录raw可放音乐文件
1
2
3
4
5
6
7
8
|
MediaPlayer
mediaplayer=MediaPlayer.create(context, R.raw.uri);
mediaplayer.setLooping( true );
mediaplayer.setVolume( 1 .0f,
1 .0f);
mediaplayer.start();
abortBroadcast();
|
超级管理员:
Android 2.2引入了支持企业应用程序提供Android设备管理API。设备管理API提供了设备管理功能在系统水平。这些api允许您创建安全性敏感的应用程序是有用的在企业环境中,IT专业人员需要丰富的控制员工的设备。例如,内置Android电子邮件应用程序利用了新的api来改善交流的支持。通过电子邮件应用程序,交流管理员可以执行密码策略——包括字母数字密码或数字针——在设备。管理员也可以远程擦除(即恢复工厂默认值)丢失或被盗的手机。用户可以同步他们的电子邮件和日历数据交换。
Email client
Security application that to remove wipe
Device management service and application
一键锁屏应用:能够一键锁屏,一键卸载
步骤:
1、先创建admim类继承DeviceAdminReceiver
2、配置清单文件(参考api文档)
1
2
3
4
5
6
7
8
|
<receiver
android:description= "@string/sample_device_admin_description"
android:label= "@string/sample_device_admin"
android:name= "com.cca.yijian.Admin"
android:permission= "android.permission.BIND_DEVICE_ADMIN" >
<!--
元数据,提供设备的超级管理员的配置信息 -->
<meta-data
android:name= "android.app.device_admin"
android:resource= "@xml/device_admin_sample" >
<intent-filter>
</action></intent-filter>
</meta-data></receiver>
|
还要新建一个 res目录下xml文件夹并新建device_admin_sample.xml:
声明中使用的安全策略的元数据提供了特定于设备管理员的附加信息,可通过DeviceAdminInfo类进行解析查看,以下为device_admin_sample.xml:的内容
1
2
3
4
5
6
7
8
9
10
11
12
|
<uses-policies>
<limit-password>
<watch-login>
<reset-password>
<force-lock>
<wipe-data>
<expire-password>
<encrypted-storage>
<disable-camera>
</disable-camera></encrypted-storage></expire-password></wipe-data></force-lock></reset-password></watch-login></limit-password></uses-policies>
</device-admin>
|
3、主活动中书写代码
点击按钮一键锁屏:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public
void
lockscreen(View view){
DevicePolicyManager
dpm=(DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
ComponentName
who= new
ComponentName( this ,
Admin. class );
if (dpm.isAdminActive(who)){
dpm.lockNow();
finish();
} else {
Toast.makeText( this ,
"请先激活应用程序" ,
0 ).show();
}
}
|
使用时:先来到系统设置界面,找到安全、进入设备管理器、找到一键锁屏,点击激活一键锁屏,此时可以使用了。
先激活应用程序
给用户一个很好的体验:来个按钮“先激活应用程序”
1
2
3
4
5
6
|
Intent
intent = new
Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
ComponentName
who= new
ComponentName( this ,
Admin. class );
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
who);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "请大家赶紧去激活程序吧,首次激活有大礼包!" );
startActivity(intent);
|
一键卸载
再来个卸载按钮:
1
2
3
4
5
6
7
8
9
10
|
public
void
deleteLockScreen(View view){
DevicePolicyManager
dpm=(DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
ComponentName
who= new
ComponentName( this ,
Admin. class );
dpm.removeActiveAdmin(who);
Intent
intent= new
Intent();
intent.setAction(Intent.ACTION_DELETE);
intent.setData(Uri.parse( "package:" +getPackageName()));
startActivity(intent);
}
|
获取位置的经纬度(真实标准坐标)在中国要转换成火星坐标才能真正确定位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
protected
void
onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocationManager
lm=(LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria
criteria= new
Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.POWER_HIGH);
String
provider =lm.getBestProvider(criteria, true );
lm.requestLocationUpdates(provider,
0 ,
0 ,
new
LocationListener() {
@Override
public
void
onStatusChanged(String provider, int
status, Bundle extras) {
}
@Override
public
void
onProviderEnabled(String provider) {
}
@Override
public
void
onProviderDisabled(String provider) {
}
@Override
public
void
onLocationChanged(Location location) {
location.getLatitude();
location.getLongitude();
System.out.println( "纬度:" +location.getLatitude()+ "------经度:" +location.getLongitude());
TextView
text= new
TextView(getApplication());
text.setTextColor(Color.RED);
text.setText( "纬度:" +location.getLatitude()+ "------经度:" +location.getLongitude());
}
}
);
}
|
标准坐标—->>中国的火星坐标
使用算法:导入modifyOffset.java和axisoffset.dat
直接到代码中使用:
1
2
3
4
5
6
7
8
9
10
|
ModifyOffset
no =ModifyOffset.getInstance(context.getClassLoader().getResourceAsStream( "axisoffset.dat" ));
PointDouble
pt = new
PointDouble(x,y);
PointDouble
marpoint=mo.s2c(pt);
System.out.println(marpoint.toString());
|
listView的简单优化
容易内存溢出
1、尽量复用convertview历史的缓存,减少创建新的view对象
2、尽量的减少子孩子的id的查询次数,定义一个viewHolder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
View
view;
viewHolder
holder;
if (convertView!= null ){
view=convertView;
holder=(viewHolder)
view.getTag();
} else {
holder= new
viewHolder();
view=View.inflate(getApplicationContext(),
R.layout.item_callsmssafe, null );
holder.black_phone=(TextView)
view.findViewById(R.id.tv_black_phone);
holder.black_mode=(TextView)
view.findViewById(R.id.tv_black_mode);
view.setTag(holder);
}
class
viewHolder{
public
TextView black_phone;
public
TextView black_mode;
public
ImageView black_delete;
}
|
listView显示数据库中的数据时,当listview发生变化时应更新listview数据
1
2
|
adapter.notifyDataSetChanged();
|
在清单文件中配置广播接收者的特点是:不管应用程序进程是否存在都能接受到对应广播