LG手机收不到/发不出彩信最有效的解决办法
现象
安卓手机无法收发彩信
解决
1. 手机支持彩信功能,但需要网络运营商支持才可以使用(手机卡需开通彩信业务)。
2. 如已开通,建议查看手机是否可以上网,建议在菜单【设置】无线和网络移动网络已启用数据勾选开启上网功能尝试。
3. 如上网正常,可能接受彩信文件过大,建议用手机编辑一条彩信发送到自己的手机上查看是否正常。
4. 如接受自己发的正常,则手机彩信功能正常;如还是无法接收,建议换其他电话卡尝试。
5. 仍旧无法正常使用,建议进入菜单【设置】无线和网络(更多)移动网络接入点名称 点触左下角菜单 重置默认网络,然后重启手机。
6. 仍旧不能实现可以建议设置一下彩信参数(一般不需要设置),建议备份数据恢复出厂设置,在手机点击软件更新升级或进入 LG官网升级尝试。
7. 排查以上仍不正常,建议送检。
现在的手机app到处都并且一般的都是可以直接付款了,现在的支付宝付款接口是支持pc,手机及app版本了,在开始中我们会用到支付宝私钥与公钥问题了,下面整理了一篇文章一起来看看。项目需要,需要在客户端集成支付宝接口。就研究了一下:因为使用支付宝接口,就需要到支付宝官网:注册帐号,并申请。下面讲的是申请好之后的操作。登录成功之后, 店家我的商家服务—在页面的下方找到——>签约管理—>找打 移动支付—–>点击下载集成文档—>跳到新的页面,在页面下方—>找到下载开发包,下载移动支付即可。然后解压出来之后一般会得到三个文件夹。
这个时候要打开文件名为: 支付宝钱包支付接口开发包2.0标准版的文件。打开之后有一个Demo 文件。打开Demo文件。里面会有三个文件夹:第一个 openssl; 第二个 服务端 Demo,第三个 客户端demo. 这个时候,我们需要关心的是 openssl 文件与 客户端Demo 的文件。
在第三个Demo文件中有IOS版与Android 版的Demo.但是你要部署运行的时候,会发现不能运行成功。在项目主文件里面这样一段代码:
//商户PID
public static final String PARTNER = "";
//商户收款账号
public static final String SELLER = "";
//商户私钥,pkcs8格式
public static final String RSA_PRIVATE = "";
//支付宝公钥
public static final String RSA_PUBLIC = "";
因为这些,都是需要根据商户注册的信息来填写的。所以就算下下载了Demo,也没有用。下面讲的就是如何获取私钥与支付宝公钥。
还记得刚刚我们加压之后的openssl文件嘛?获取私钥与公钥的方法就在里面:
首先打开openssl文件:以下是文件打开顺序: openssl–>bin –> 双击 openssl.exe文件。这个时候会出现一个命令框:(首先要说明的是这个文件是在Windows系统下打开的)要是苹果系统好像不行.接着继续往下说:
打开命令框后:输入第一行命令 ,生成私钥,如下:
genrsa -out rsa_private_key.pem 1024
按回车键,接着输入第二行命令,生成公钥:
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
按回车键,接着输入第三行命令,将RSA私钥转换成PKCS8格式
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
执行完这三行命令后,就生成了两个以:.pem 结尾的文件。这就是我们生成的公钥与私钥.文件位置就在: bin 目录下。当然我们打不开这两个文件。但是我们可以复制一份到桌面,改成Txt文件打开即可。因为我们需要的只是里面的字符串,记住当我们引用这两个长的字符串的时候,需要注意的是:字符串,不能包括,换行,空格,以及其他误加的字符。所以复制的时候一定要小心。
当然私钥就是我们需要的私钥了,如何获得支付宝公钥呢:回到支付宝首先,首先登录,
一: 点击“查看PID|KEY”,在新打开的页面(https://b.alipay.com/order/pidAndKey.htm ),可查看到签约支付宝账号、合作者身份ID(PID.
二:输入支付密码,查询key、支付宝公钥。
三:上传RSA公钥,在“合作伙伴密钥管理”下,点击“RSA加密”后的“添加密钥”,把自己的公钥复制进去。注意不能有空格,换
行之类的。
:点击确认上传,若是提示上传成功。则就是成功。
这个时候就可查看支付宝公钥了。如图:
至此,将对应的私钥与公钥填到相应位置我们的Demo 就可一运行了。然后集成到项目中即可。就需要自己动手了。遇到问题,百度一下。希望给你带来用处。
安卓手机的图形锁(九宫格)是3×3的点阵,按次序连接数个点从而达到锁定/解锁的功能。最少需要连接4个点,最多能连接9个点。网上也有暴力删除手机图形锁的方法,即直接干掉图形锁功能。本文我们来看看另外一种破解方法。
前提条件:手机需要root,而且打开调试模式。一般来讲,如果用过诸如“豌豆荚手机助手”、“360手机助手”一类的软件,都会被要求打开调试模式的。如果要删除手机内置软件,则需要将手机root。
原理分析
首先科普一下,安卓手机是如何标记这9个点的。通过阅读安卓系统源码可知,每个点都有其编号,组成了一个3×3的矩阵,形如:
12300 01 02
03 04 05
06 07 08
假如设定解锁图形为一个“L”形,如图:
那么这几个点的排列顺序是这样的:00 03 06 07 08。系统就记下来了这一串数字,然后将这一串数字(以十六进制的方式)进行SHA1加密,存储在了手机里的/data/system/gesture.key 文件中。我们用数据线连接手机和电脑,然后ADB连接手机,将文件下载到电脑上(命令:adb pull /data/system/gesture.key gesture.key),如图:
用WinHex等十六进制编辑程序打开gesture.key,会发现文件内是SHA1加密过的字符串:c8c0b24a15dc8bbfd411427973574695230458f0,如图:
当你下次解锁的时候,系统就对比你画的图案,看对应的数字串是不是0003060708对应的加密结果。如果是,就解锁;不是就继续保持锁定。那么,如果穷举所有的数字串排列,会有多少呢?联想到高中的阶乘,如果用4个点做解锁图形的话,就是9x8x7x6=3024种可能性,那5个点就是 15120,6个点的话60480,7个点181440,8个点362880,9个点362880。总共是985824种可能性(但这么计算并不严密,因为同一条直线上的点只能和他们相邻的点相连)。
满打满算,也不到985824种可能性。乍一看很大,但在计算机面前,穷举出来这些东西用不了几秒钟。
破解过程
知道了原理,就着手写程序来实现吧。这里使用了Python来完成任务。主要应用了hashlib模块(对字符串进行SHA1加密)和itertools模块(Python内置,生成00-09的排列组合)。
主要流程为:
1.ADB连接手机,获取gesture.key文件
2.读取key文件,存入字符串str_A
3.生成全部可能的数字串
4.对这些数字串进行加密,得到字符串str_B
5.将字符串str_A与str_B进行对比
6.如果字符串A,B相同,则说明数字串num就是想要的解锁顺序
7.打印出数字串num
下面为程序:
# -*- coding: cp936 -*-
import itertools
import hashlib
import time
import os
#调用cmd,ADB连接到手机,读取SHA1加密后的字符串
os.system("adb pull /data/system/gesture.key gesture.key")
time.sleep(5)
f=open('gesture.key','r')
pswd=f.readline()
f.close()
pswd_hex=pswd.encode('hex')
print '加密后的密码为:%s'%pswd_hex
#生成解锁序列,得到['00','01','02','03','04','05','06','07','08']
matrix=[]
for i in range(0,9):
str_temp = '0'+str(i)
matrix.append(str_temp)
#将00——08的字符进行排列,至少取4个数排列,最多全部进行排列
min_num=4
max_num=len(matrix)
for num in range(min_num,max_num+1):#从04 -> 08
iter1 = itertools.permutations(matrix,num)#从9个数字中挑出n个进行排列
list_m=[]
list_m.append(list(iter1))#将生成的排列全部存放到 list_m 列表中
for el in list_m[0]:#遍历这n个数字的全部排列
strlist=''.join(el)#将list转换成str。[00,03,06,07,08]-->0003060708
strlist_sha1 = hashlib.sha1(strlist.decode('hex')).hexdigest()#将字符串进行SHA1加密
if pswd_hex==strlist_sha1:#将手机文件里的字符串与加密字符串进行对比
print '解锁密码为:',strlist
总结
从程序本身来说,得到解锁密码后应该用break跳出循环并终止程序运行。但Python并没有跳出多重循环的语句,如果要跳出多重循环,只能设置标志位然后不停进行判定。为了运行速度就略去了“跳出循环”这个步骤。(有没有更好的实现跳出多重循环的方法?)另外也略去了很多容错语句。从破解目的来说,如果单单是忘记了自己的手机图形锁密码,完全可以用更简单的办法:ADB连接手机,然后“adb rm /data/system/gesture.key”删除掉gesture.key文件,此时图形锁就失效了,随意画一下就能解锁。但本文开篇假设的是“为了不被察觉地进入到别人的手机里”,所以就有了这篇文章。
最后提一个安全小建议:如果手机已root,还要用“XX手机助手”,还想设置图形锁的话——在手机“设置”选项里,有一个“锁定状态下取消USB调试模式”(这个名字因手机而异,而且有的有此选项,有的手机就没有),开启此功能之后,在手机锁定状态下就能够防范此类攻击了。此文技术原理很简单,还望各位大大传授些高大上的Python编程技巧。
这里我们采用经典的左中右布局,也可以根据项目需要自行调整,比如在右侧再加一个控件,或者将标题偏左都可以
注:其中应用到了上一篇文章中的ButtonM控件,大家可以先简单了解一下。
还是先来看一下效果图:
下面来看代码实现,共四个文件两个java类,两个布局文件
1 TitleBarM.java
package landptf.control;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* 继承RelativeLayout,自定义标题栏
* @author landptf
* @date 2015-6-10
*/
public class TitleBarM extends RelativeLayout{
private Context context;
//定义三个控件,
private ButtonM btnLeft;
private TextView tvTitle;
private ButtonM btnRight;
//定义左侧控件的接口
private OnClickListenerL onClickListenerL = null;
//定义右侧控件的接口
private OnClickListenerR onClickListenerR = null;
public interface OnClickListenerL{
//定义一个方法
public void onClick(View v);
}
public interface OnClickListenerR{
//定义一个方法
public void onClick(View v);
}
/**
* 为左侧控件绑定事件
* @param onClickListenerL
*/
public void setOnClickLisenerL(OnClickListenerL onClickListenerL) {
this.onClickListenerL = onClickListenerL;
}
/**
* 为右侧控件绑定事件
* @param onClickListenerR
*/
public void setOnClickLisenerR(OnClickListenerR onClickListenerR) {
this.onClickListenerR = onClickListenerR;
}
public TitleBarM(Context context) {
this(context, null);
}
public TitleBarM(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public TitleBarM(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
//设置RelativeLayout的布局
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
//设置默认的背景色
setBackgroundColor(Color.parseColor("#B674D2"));
init();
}
private void init() {
//初始化左侧ButtonM
btnLeft = new ButtonM(context);
RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
//垂直居中
lp.addRule(RelativeLayout.CENTER_VERTICAL);
//设置距离左侧10dp
lp.leftMargin = dp2px(context, 10);
btnLeft.setLayoutParams(lp);
btnLeft.setTextSize(16);//设置字体大小,默认为16
btnLeft.setTextColori(Color.WHITE);//默认字体颜色为白色
btnLeft.setTextColorSelected("#909090");//按下后的字体颜色
//定义其点击事件
btnLeft.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onClickListenerL != null) {
onClickListenerL.onClick(v);
}
}
});
//初始化中间标题控件
tvTitle = new TextView(context);
lp=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
//使其处于父控件的中间位置,也有一些APP的标题偏左,可根据项目需要自行调整,也可动态设置
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
tvTitle.setLayoutParams(lp);
//设置标题文字颜色
tvTitle.setTextColor(Color.WHITE);
//设置标题文字大小
tvTitle.setTextSize(18);//默认为18
//初始化右侧ButtonM
btnRight = new ButtonM(context);
lp=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
lp.rightMargin = dp2px(context, 10);
//垂直居中
lp.addRule(RelativeLayout.CENTER_VERTICAL);
//居于父控件的右侧
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
btnRight.setLayoutParams(lp);
btnRight.setTextSize(16);//默认有16
btnRight.setVisibility(View.GONE); //默认隐藏右侧控件
btnRight.setTextColori(Color.WHITE);
btnRight.setTextColorSelected("#909090");
btnRight.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onClickListenerR != null) {
onClickListenerR.onClick(v);
}
}
});
//分别将三个控件加入到容器中
addView(btnLeft);
addView(tvTitle);
addView(btnRight);
}
/**
* 设置标题栏的背景色 ,String
* @param backColors
*/
public void setBackColor(String backColors) {
setBackgroundColor(Color.parseColor(backColors));
}
/**
* 设置标题栏的背景色 ,int
* @param backColori
*/
public void setBackColor(int backColori) {
setBackgroundColor(backColori);
}
/**
* 设置左侧控件显示的文字
* @param leftText
*/
public void setLeftText(String leftText) {
btnLeft.setText(leftText);
}
/**
* 设置左侧控件的背景图
* @param leftBackImage
*/
public void setLeftBackImage(int leftBackImage) {
if (leftBackImage != 0) {
btnLeft.setBackGroundImage(leftBackImage);
}
}
/**
* 设置左侧控件选中的背景图
* @param leftBackImageSeleted
*/
public void setLeftBackImageSeleted(int leftBackImageSeleted) {
if (leftBackImageSeleted != 0) {
btnLeft.setBackGroundImageSeleted(leftBackImageSeleted);
}
}
/**
* 设置左侧控件显示属性,默认为显示
* @param leftVisible
*/
public void setLeftVisible(boolean leftVisible) {
btnLeft.setVisibility(leftVisible ? View.VISIBLE : View.GONE);
}
/**
* 设置左侧控件显示的字体大小
* @param leftTextSize
*/
public void setLeftTextSize(float leftTextSize) {
btnLeft.setTextSize(leftTextSize);
}
/**
* 设置中间控件显示属性,默认为显示
* @param leftVisible
*/
public void setTitleVisible(boolean titleVisible) {
tvTitle.setVisibility(titleVisible ? View.VISIBLE : View.GONE);
}
/**
* 设置中间控件的文字
* @param titleText
*/
public void setTitleText(String titleText) {
tvTitle.setText(titleText);
}
/**
* 设置中间控件的文字的大小
* @param titleTextSize
*/
public void setTitleTextSize(float titleTextSize) {
tvTitle.setTextSize(titleTextSize);
}
/**
* 设置右侧控件显示的文字
* @param leftText
*/
public void setRightText(String rightText) {
btnRight.setText(rightText);
}
/**
* 设置右侧控件的背景图
* @param leftBackImage
*/
public void setRightBackImage(int rightBackImage) {
if (rightBackImage != 0) {
btnRight.setBackGroundImage(rightBackImage);
}
}
/**
* 设置右侧控件选中的背景图
* @param leftBackImageSeleted
*/
public void setRightBackImageSeleted(int rightBackImageSeleted) {
if (rightBackImageSeleted != 0) {
btnRight.setBackGroundImageSeleted(rightBackImageSeleted);
}
}
/**
* 设置右侧控件显示的字体大小
* @param leftTextSize
*/
public void setRightTextSize(float rightTextSize) {
btnRight.setTextSize(rightTextSize);
}
/**
* 设置右侧控件显示属性,默认为隐藏
* @param leftVisible
*/
public void setRightVisible(boolean rightVisible) {
btnRight.setVisibility(rightVisible ? View.VISIBLE : View.GONE);
}
//定义一个私有方法dp2px
private int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
}
以上定义了一些public方法,可根据具体项目需求扩展或减少。
2 child_titlebarm.xml 这里将标题栏单独写成一个布局文件,在其他布局文件中直接include即可
<?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="50dp"
android:orientation="vertical" >
<landptf.control.TitleBarM
android:id="@+id/tbm_title"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</landptf.control.TitleBarM>
</LinearLayout>
这里标题栏的高低默认设成50dp
3 activity_titlebar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:ignore="HardcodedText" >
<include
android:id="@+id/title"
layout="@layout/child_titlebarm" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="测试标题栏"
android:textSize="20sp" />
</RelativeLayout>
里面比较简单只include一个child_titlebarm.xml,又定义一个TextView就不做特别说明
4 TitleBarMActivity.java
package landptf.control;
import landptf.control.TitleBarM.OnClickListenerL;
import landptf.control.TitleBarM.OnClickListenerR;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
/**
* TitleBarM测试类
* @author landptf
* @date 2015-6-10
*/
public class TitleBarMActivity extends Activity{
private TitleBarM tbTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_titlebarm);
initView();
}
private void initView() {
//初始化控件
tbTitle = (TitleBarM) findViewById(R.id.tbm_title);
//先来设置一个背景色,当然你也可以用默认的背景色
tbTitle.setBackColor("#7067E2");
//设置左侧文字显示文字,也可设置背景图
tbTitle.setLeftText("返回");
//设置左侧控件点击事件
tbTitle.setOnClickLisenerL(new OnClickListenerL() {
@Override
public void onClick(View v) {
Toast.makeText(TitleBarMActivity.this, "你点击了返回", Toast.LENGTH_SHORT).show();
}
});
//设置中间的标题
tbTitle.setTitleText("landptf");
//由于我们将右侧的控件默认为隐藏,在此显示出来
tbTitle.setRightVisible(true);
//设置右侧的控件的背景图,这里找了两张搜索的图片
tbTitle.setRightBackImage(R.drawable.title_search);
tbTitle.setRightBackImageSeleted(R.drawable.title_search_selected);
tbTitle.setOnClickLisenerR(new OnClickListenerR() {
@Override
public void onClick(View v) {
Toast.makeText(TitleBarMActivity.this, "你点击了搜索", Toast.LENGTH_SHORT).show();
}
});
}
}
以上便是全部代码,其中使用了上一篇文章中介绍的ButtonM控件,大家也可以根据自己的需要使用其他控件实现。
这里只提供一种思路,不足之处互相交流学习。
我们都知道ContentProvider是用来共享数据的,然而android本身就提供了大量的ContentProvider,例如联系人信息,系统的多媒体信息等,这些系统的ContentProvider都提供了供其他应用程序访问的Uri,开发者可以通过ContentResolver来调用系统的ContentProvider提供的insert()/update()/delete()/query()方法,从而实现自己的需求。
1、了解系统联系人的结构
(1)android系统对联系人管理提供了很多的Uri,其中用到最多的几个如下:
ContactsContract.Contacts.CONTENT_URI:管理联系人的Uri
ContactsContract.CommonDataKinds.Phone.CONTENT_URI:管理联系人电话的Uri
ContactsContract.CommonDataKinds.Email.CONTENT_URI:管理联系人邮箱的Uri
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI:管理联系人地址的Uri
我们可以根据系统提供的这些Uri去操作系统联系人信息,具体的还有很多CONTENT_URI,可以到ContactsContract.class文件中去查看源码。
(2)表结构
我们之前说过,ContentProvider是以表的形式来存放这些数据的,系统联系人也是这样,一般存放在data/data/com.android.providers.contacts/databases/contacts2.db中,我们可以通过adb shell命令行的方式来看,也可以将这个contacts2.db文件导出,通过sqlite工具来查看,这里为了方便我们导出来看一下。
找到对应的文件,然后选中点击右上角的导出按钮,将文件导出到系统中的某一个地方
将导出的文件用工具打开,我这里使用的是:Navicat Premium
表和视图:
我们经常用的到有:contacts、data、raw_contacts三张表:
contacts表:
_id :表的ID,主要用于其它表通过contacts 表中的ID可以查到相应的数据。
display_name: 联系人名称
photo_id:头像的ID,如果没有设置联系人头像,这个字段就为空
times_contacted:通话记录的次数
last_time_contacted: 最后的通话时间
lookup :是一个持久化的储存 因为用户可能会改名子 但是它改不了lookup
data表:
raw_contact_id:通过raw_contact_id可以找到 raw_contact表中相对的数据。
data1 到 data15 这里保存着联系人的信息 联系人名称 联系人电话号码 电子邮件 备注 等等
raw_contacts表:
version :版本号,用于监听变化
deleted :删除标志, 0为默认 1 表示这行数据已经删除
display_name : 联系人名称
last_time_contacts : 最后联系的时间
【说明:由于这些表的字段都特别多,截图不全,可以自己试着导出一份看看】
2、代码实现
(1)首先要在AndroidManifest.xml文件中配置对系统联系人的读写权限:
<!-- 添加操作联系人的权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
(2)布局文件
首先是列表展示页面:
<?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="fill_parent"
android:layout_height="50dp"
android:gravity="center_vertical"
android:text="我的联系人"
android:textSize="25dp" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@android:color/darker_gray" >
<TextView
android:id="@+id/id"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:text="ID"
android:gravity="center" />
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:text="姓名"
android:gravity="center" />
<TextView
android:id="@+id/phone"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:text="手机号码"
android:gravity="center" />
</LinearLayout>
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:divider="#FF0000"
android:dividerHeight="1dp"
android:focusable="true"
android:minHeight="40dp"
android:footerDividersEnabled="false" >
</ListView>
</LinearLayout>
列表展示中需要用的listview页面布局:
<?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="horizontal" >
<TextView
android:id="@+id/id"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
/>
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
/>
<TextView
android:id="@+id/phone"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:layout_height="40dp"
/>
</LinearLayout>
添加联系人界面:
<?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" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:orientation="horizontal" >
<TextView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:gravity="center_vertical|right"
android:text="姓名:"
android:textSize="20dp" />
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:orientation="horizontal" >
<TextView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="center_vertical|right"
android:layout_marginRight="20dp"
android:text="手机号码:"
android:textSize="20dp" />
<EditText
android:id="@+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal" >
<Button
android:id="@+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存"
android:textSize="20sp"
/>
<Button
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
android:layout_marginLeft="30dp"
android:textSize="20sp"
/>
</LinearLayout>
</LinearLayout>
联系人详细界面:
<?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="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:background="@android:color/darker_gray" >
<TextView
android:id="@+id/tv_name"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@android:color/white"
android:gravity="center_vertical|right"
android:text="姓名:"
android:textSize="20sp" />
<TextView
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/tv_name"
android:layout_toRightOf="@+id/tv_name"
android:background="@android:color/white"
android:gravity="center_vertical"
android:text=""
android:textSize="20sp" />
<TextView
android:id="@+id/tv_phone"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_name"
android:layout_marginTop="20dp"
android:background="@android:color/white"
android:gravity="center_vertical|right"
android:text="手机号:"
android:textSize="20sp" />
<TextView
android:id="@+id/et_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/tv_phone"
android:layout_toRightOf="@+id/tv_phone"
android:background="@android:color/white"
android:gravity="center_vertical"
android:text=""
android:textSize="20sp" />
<TextView
android:id="@+id/tv_email"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_phone"
android:layout_marginTop="20dp"
android:background="@android:color/white"
android:gravity="center_vertical|right"
android:text="Email:"
android:textSize="20sp" />
<TextView
android:id="@+id/et_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/tv_email"
android:layout_toRightOf="@+id/tv_email"
android:background="@android:color/white"
android:gravity="center_vertical"
android:text=""
android:textSize="20sp" />
<TextView
android:id="@+id/tv_address"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_email"
android:layout_marginTop="20dp"
android:background="@android:color/white"
android:gravity="center_vertical|right"
android:text="地址:"
android:textSize="20sp" />
<TextView
android:id="@+id/et_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/tv_address"
android:layout_toRightOf="@+id/tv_address"
android:background="@android:color/white"
android:gravity="center_vertical"
android:text=""
android:textSize="20sp" />
</RelativeLayout>
程序中需要用的menu菜单配置在menu文件中:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group android:id="@+id/group1">
<item android:id="@+id/detail" android:title="详情"></item>
<item android:id="@+id/update" android:title="修改"></item>
<item android:id="@+id/delete" android:title="删除"></item>
</group>
</menu>
(3)Activity代码:
列表页面以及适配器Adapter
ContactsActivity.java
package com.demo.contentprovider;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.Toast;
import com.demo.adapter.ContactsAdapter;
import com.demo.model.Contact;
/**
* 手机联系人操作
* @author yinbenyang
*/
public class ContactsActivity extends Activity {
private static final int ADD = 0;
private static final int REQUEST_ADD = 100;
// 存储联系人的列表
private ArrayList<Contact> contactList = null;
// 联系人适配器
private ContactsAdapter adapter;
private ListView listview;
// 弹出式菜单
public PopupMenu popupmenu = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contentprovider);
listview = (ListView) findViewById(R.id.listview);
init();
listview.setOnItemLongClickListener(new OnItemLongClickListenerImpl());
// registerForContextMenu(listview);
}
// ----------------------------------------------------选项菜单---------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
menu.add(0, ADD, 0, "添加");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case ADD:
Intent intent = new Intent(this, AddContactActivity.class);
startActivityForResult(intent, REQUEST_ADD);
break;
default:
break;
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
switch (requestCode) {
case REQUEST_ADD:
init();
break;
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
// 初始化,获取联系人
private void init() {
ContentResolver resolver = getContentResolver();
/**
* ContactsContract.Contacts.CONTENT_URI:手机联系人的Uri:content://com.android
* .contacts/contacts
* sort_key_alt:它里面保存的是联系人名字的拼音字母,例如联系人名字是“李明”,则sort_key保存的是“LI李MING明”,
* 这样如果是按sort_key或sort_key_alt排序的话,就可以将联系人按顺序排列
*/
Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, "sort_key_alt");
contactList = new ArrayList<Contact>();
while (cursor.moveToNext()) {
Contact contact = new Contact();
String phoneNumber = null;
String name = cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String id = cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phoneCursor = resolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = "
+ id, null, null);
while (phoneCursor.moveToNext()) {
phoneNumber = phoneCursor
.getString(phoneCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
contact.setId(Integer.parseInt(id));
contact.setName(name);
contact.setPhone(phoneNumber);
contactList.add(contact);
}
adapter = new ContactsAdapter(this, contactList);
listview.setAdapter(adapter);
}
private class OnItemLongClickListenerImpl implements
OnItemLongClickListener {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
final int position, long id) {
final ContentResolver resolver = getContentResolver();
popupmenu = new PopupMenu(ContactsActivity.this, listview);
popupmenu.getMenuInflater().inflate(R.menu.my_menu,
popupmenu.getMenu());
popupmenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.detail:
String id = contactList.get(position).getId() + "";
Intent intent = new Intent(ContactsActivity.this,
ContactDetailActivity.class);
intent.putExtra("id", id);
startActivity(intent);
break;
case R.id.update:
Toast.makeText(ContactsActivity.this, "执行修改操作",
Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
new AlertDialog.Builder(ContactsActivity.this)
.setTitle("?h除联系人")
.setMessage("你确定要删除该联系人吗?")
.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
int i = resolver
.delete(ContactsContract.RawContacts.CONTENT_URI,
ContactsContract.Data._ID
+ " = "
+ contactList
.get(position)
.getId(),
null);
Toast.makeText(ContactsActivity.this,
i == 1 ? "?h除成功!" : "?h除失?。?quot;,
Toast.LENGTH_SHORT).show();
init();
}
})
.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
}).create().show();
break;
default:
break;
}
// Toast.makeText(ContactsActivity.this,
// "你点击了:" + item.getTitle(), Toast.LENGTH_SHORT)
// .show();
// popupmenu.dismiss();
return true;
}
});
popupmenu.show();
return true;
}
}
}
/**
* <!-- 联系人相关的uri --> content://com.android.contacts/contacts 操作的数据是联系人信息Uri
* content://com.android.contacts/data/phones 联系人电话Uri
* content://com.android.contacts/data/emails 联系人Email Uri
*/
ContactsAdapter.java
package com.demo.adapter;
import java.util.ArrayList;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.demo.contentprovider.R;
import com.demo.model.Contact;
/**
* 联系人的Adapter
*
* @author yinbenyang
*/
public class ContactsAdapter extends BaseAdapter {
private Context context;
private ArrayList<Contact> listContact;
public ContactsAdapter(Context context, ArrayList<Contact> listContact) {
this.context = context;
this.listContact = listContact;
}
@Override
public int getCount() {
return listContact.size();
}
@Override
public Object getItem(int position) {
return listContact.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = View
.inflate(context, R.layout.listview_contact, null);
holder = new ViewHolder();
holder.id = (TextView) convertView.findViewById(R.id.id);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.phone = (TextView) convertView.findViewById(R.id.phone);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Contact con = listContact.get(position);
holder.id.setText(con.getId().toString());
holder.name.setText(con.getName());
holder.phone.setText(con.getPhone());
return convertView;
}
static class ViewHolder {
TextView id;
TextView name;
TextView phone;
}
}
添加联系人Activity:
AddContactActivity.java
package com.demo.contentprovider;
import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
/**
* 添加联系人信息
* @author yinbenyang
*
*/
public class AddContactActivity extends Activity implements OnClickListener{
private EditText name,phone;
private Button save,cancel;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.addcontact);
name = (EditText) findViewById(R.id.name);
phone = (EditText) findViewById(R.id.phone);
save = (Button) findViewById(R.id.save);
cancel = (Button) findViewById(R.id.cancel);
save.setOnClickListener(this);
cancel.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.save:
String _name = name.getText().toString().replaceAll(" ", "");
String _phone = phone.getText().toString().replaceAll(" ","");
ContentValues values = new ContentValues();
//首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
Uri rawContactUri =getContentResolver().insert(RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
//往data表入姓名数据
values.clear();
values.put(Data.RAW_CONTACT_ID, rawContactId);
//设置内容类型
values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
//设置内容名字
values.put(StructuredName.GIVEN_NAME, _name);
getContentResolver().insert(
ContactsContract.Data.CONTENT_URI, values);
//往data表入电话数据
values.clear();
values.put(Data.RAW_CONTACT_ID, rawContactId);
values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
//设置电话号码
values.put(Phone.NUMBER, _phone);
//设置电话类型
values.put(Phone.TYPE, Phone.TYPE_MOBILE);
getContentResolver().insert(
ContactsContract.Data.CONTENT_URI, values);
this.finish();
break;
case R.id.cancel:
this.finish();
break;
default:
break;
}
}
}
联系人详细页面:
ContactDetailActivity.java
package com.demo.contentprovider;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.TextView;
/**
* 联系人详细信息
*
* @author yinbenyang
*
*/
public class ContactDetailActivity extends Activity {
private TextView et_name, et_phone, et_email, et_address;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contactdetail);
et_name = (TextView) findViewById(R.id.et_name);
et_phone = (TextView) findViewById(R.id.et_phone);
et_email = (TextView) findViewById(R.id.et_email);
et_address = (TextView) findViewById(R.id.et_address);
Intent intent = getIntent();
String id = intent.getStringExtra("id");
ContentResolver resolver = getContentResolver();
// 查找姓名
Cursor nameCursor = resolver.query(
ContactsContract.Contacts.CONTENT_URI,
null,
ContactsContract.Contacts._ID + " = " + id,
null, null);
while(nameCursor.moveToNext()){
et_name.setText(nameCursor.getString(nameCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
}
// 查找手机号
Cursor phoneCursor = resolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id,
null, null);
while (phoneCursor.moveToNext()) {
et_phone.setText(phoneCursor.getString(phoneCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
}
// 查找邮箱
Cursor emailCursor = resolver.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + id,
null, null);
while (emailCursor.moveToNext()) {
et_email.setText(emailCursor.getString(emailCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)));
}
// 查找地址
Cursor addressCursor = resolver.query(
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID
+ " = " + id, null, null);
while (addressCursor.moveToNext()) {
et_address
.setText(addressCursor.getString(addressCursor
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.DATA)));
}
}
}
最后效果图如下。可以实现联系人的添加,删除和修改功能:
相关文章
- 409错误是什么?http 409错误怎么解决呢?不少站长在遇到这个错误代码之后都一筹莫展,本次一聚教程网为大家带来了详细的说明,快来看看吧。 409错误是什么: HTTP 40...2017-01-22
PHP session_start()很慢问题分析与解决办法
本文章来给各位同学介绍一下关于PHP session_start()很慢问题分析与解决办法,希望碰到此问题的同学可进入参考。 最近在做东西的时候发现一个问题 有一个接口挂...2016-11-25- 支付宝支付在国内算是大家了,我们到处都可以使用支付宝了,下文整理介绍的是在安卓app应用中使用支付宝进行支付的开发例子。 之前讲了一篇博客关与支付宝集成获取...2016-09-20
- http 405错误是什么?http 405错误怎么解决?相信很多站长都在找这两个问题的答案,本次小编为大家带来了详细的教程,快来看看吧。 405错误是什么: HTTP 405错误是H...2017-01-22
php中json_decode()和json_encode()用法与中文不显示解决办法
本文章介绍了关于php中json_decode()和json_encode()用法与中文不显示解决办法,有需要的朋友可以参考一下下。 php中json_decode()和json_encode() 1.json_decode(...2016-11-25- 在php中我们如果要导入excel数据我们通常会使用phpexcel插件了,但是有朋友会发与使用phpexcel导出数据出现身份证后四位是0000情况了,下面我们就来看解决办法。 最...2016-11-25
- 401是HTTP状态码的一种,属于“请示错误”,表示请求可能出错,已妨碍了服务器对请求的处理。具体的401错误是指:未授权,请求要求进行身份验证。登录后,服务器可能会返回对页面...2017-01-22
- PHP+Ajax有许多的功能都会用到它小编今天就有使用PHP+Ajax实现的一个微信登录功能了,下面我们来看一个PHP+Ajax手机发红包的程序例子,具体如下所示。 PHP发红包基本...2016-11-25
- Apache status 503 的原因大致有如下几种情况 : 1、 CPU 负载过高,服务器响应不过来,返回503 2、 系统连接数超限,超过MaxVhostClients的上限,返回503 3、 单IP连接数超限,超过M...2016-01-28
- 403错误是HTTP状态码的一种,属于“请示错误”,表示服务器拒绝请求。如果在搜索引擎尝试抓取您网站上的有效网页时显示此状态代码,那么,这可能是您的服务器或主机拒绝搜索...2017-01-22
- 412错误是什么?412错误怎么解决?本次一聚教程网将为大家带来详细的介绍,帮助大家全面了解412错误的意思以及解决412错误的方法。 412错误是什么: HTTP 412错误,(Precond...2017-01-22
- 今天用CPAN安装Term::ReadLine,报了个这样的错误 Going to read /root/.cpan/sources/modules/03modlist.data.gz Can't locate object method "data" via package "C...2016-11-25
- HTTP 406错误是HTTP协议状态码的一种,表示无法使用请求的内容特性来响应请求的网页。一般是指客户端浏览器不接受所请求页面的 MIME 类型。 而MIME类型是在把输出...2017-01-22
- 407错误是什么?407错误怎么解决?不少站长都遇到过407错误,下面小编将告诉大家如何处理407错误。 407错误是什么: HTTP 407错误是HTTP协议状态码的一种,表示需要代...2017-01-22
- 410错误是HTTP协议状态码的一种,本次一聚教程网将为大家详细介绍HTTP 410错误是什么,以及410错误的解决办法。 410错误是什么: HTTP 410错误是HTTP协议状态码的...2017-01-22
- 华为手机怎么恢复已卸载的应用?有时候我们在使用华为手机的时候,想知道卸载的应用怎么恢复,这篇文章主要介绍了华为手机恢复应用教程,需要的朋友可以参考下...2020-06-29
- 很多用安卓智能手机的朋友是用九宫格锁屏,网上也有暴力删除手机图形锁的方法,不过我们可以用程序来破解。本文只提供技术学习,不能干坏事 安卓手机的图形锁(九宫格)...2016-09-20
- 每当遇到http错误代码为400,代表客户端发起的请求不符合服务器对请求的某些限制,或者请求本身存在一定的错误,那么HTTP 400错误怎么解决呢?请看下文介绍。 目前400错...2017-01-22
- 华为手机怎么开启双时钟?华为手机是可以设置双时钟的,如果来回在两个有时差的地方工作,是可以设置双时钟显示,下面我们就来看看华为添加双时钟的技巧,需要的朋友可以参考下...2020-12-08
- 下面给大家介绍phpstudy访问速度慢的解决办法。1、修改mysql数据库链接地址为ip地址127.0.0.1。2、使用最新版本,这个坑了我好久时间。下面一段内容是关于phpstudy启动失败的解决办法。php5.3、5.4和apache都是用vc9编...2015-11-24