安卓读取信息列表
1. 实现的功能
① 能够选定保存的方式,一种是xml形式保存,另外一种是纯文本形式的保存
② 按照下拉列表,可以选择保存以下四种信息
<item>备份所有信息</item>
<item>备份接收信息</item>
<item>备份发送信息</item>
<item>备份存在号码信息</item>
③ 点击查看按钮, 通过列表展示所有的信息
2. 实现效果图
3.实现
步骤① 实现基本的布局框架,主界面的布局采用线性布局,双按钮和单选框以及下拉栏,展示信息采用ListView
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/xx"
tools:context=".MainActivity">
<ListView
android:id="@+id/list_1"
android:layout_width="match_parent"
android:layout_height="488dp"></ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<Spinner
android:id="@+id/spinner1"
android:layout_width="118dp"
android:layout_height="match_parent"
android:layout_marginLeft="50dp"
android:entries="@array/degree"
android:spinnerMode="dialog" />
<Button
android:id="@+id/btn_1"
android:layout_marginLeft="50dp"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:background="@drawable/button_round"
android:text="查看信息" />
</LinearLayout>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="保存格式"
/>
<RadioGroup
android:id="@+id/radiogroup"
android:layout_width="163dp"
android:layout_height="50dp"
android:layout_marginLeft="0dp"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radiobutton1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="xml" />
<RadioButton
android:id="@+id/radiobutton2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="txt" />
</RadioGroup>
<Button
android:layout_toRightOf="@+id/radiogroup"
android:id="@+id/btn_2"
android:background="@drawable/button_round"
android:layout_width="wrap_content"
android:text="备份信息"
android:layout_height="50dp"/>
</LinearLayout>
</LinearLayout>
button_round.xml 按钮的美化(圆角 ,背景)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#687fa5">
</solid>
<corners
android:topLeftRadius="20dp"
android:topRightRadius="20dp"
android:bottomLeftRadius="20dp"
android:bottomRightRadius="20dp"
/>
</shape>
items.xml 每一个列表项的布局文件 ,实际显示只有前四个textview,最后一个作为分割
<?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:padding="5dp"
android:orientation="vertical">
<TextView
android:id="@+id/txt1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
<TextView
android:id="@+id/txt2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
<TextView
android:id="@+id/txt3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
<TextView
android:id="@+id/txt4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
<TextView
android:id="@+id/txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
/>
</LinearLayout>
strings.xml
<resources>
<string name="app_name">ImagesProviderDemo</string>
<string-array name="degree" Size="25sp">
<item>备份所有信息</item>
<item>备份接收信息</item>
<item>备份发送信息</item>
<item>备份存在号码信息</item>
</string-array>
</resources>
步骤② 创建一个javaBean作为打包信息类
Messageinfo.java
package com.example.imagesproviderdemo;
public class Messageinfo {
private int _id;//主键
private String address;//发送地址
private long date;//发送时间
private int type;//类型
private String body;//内容
//构造方法
public Messageinfo(int _id,String address,String body , int type, long date) {
this._id = _id;
this.address = address;
this.date = date;
this.type = type;
this.body = body;
}
public String getAddress()
{
return address;
}
public String getBody()
{
return body;
}
public int getFormatType()
{
return type;
}
public long getFormatDate()
{
return date;
}
}
步骤③ 构建ListView的Adapter
TextAdapter.java
package com.example.imagesproviderdemo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
import java.util.zip.Inflater;
public class TextAdapter extends BaseAdapter {
public List<Messageinfo>list;
private LayoutInflater mInflater;
public TextAdapter(List<Messageinfo>list, Context context)
{
super();
this.list = list;/// 接收数据
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder = null;
if(view == null) {
view = mInflater.inflate(R.layout.items, viewGroup,false);
// 可以被重用的视图 两个参数 第一个参数就是 分布的资源id 第二个就是填充的根视图
holder = new ViewHolder();
holder.txt1 = (TextView) view.findViewById(R.id.txt1);
holder.txt2 = (TextView) view.findViewById(R.id.txt2);
holder.txt3 = (TextView) view.findViewById(R.id.txt3);
holder.txt4 = (TextView) view.findViewById(R.id.txt4);
view.setTag(holder);
}
else
holder = (ViewHolder) view.getTag();
Messageinfo mess = list.get(i);
/// 填充数据
holder.txt1.setText("手机号码:" + mess.getAddress());
holder.txt2.setText( "短信内容:" + mess.getBody());
holder.txt3.setText("短信类型:" + mess.getFormatType());
holder.txt4.setText("短信发送时间:" + mess.getFormatDate());
return view;
}
/// 复用类
public final class ViewHolder{
public TextView txt1;
public TextView txt2;
public TextView txt3;
public TextView txt4;
}
}
步骤④ 添加需要的权限,在Manifests之中添加读取通讯录权限以及读取信息的权限
<uses-permission android:name="android.permission.READ_SMS" />
<!--读取联系人的权限-->
<uses-permission android:name="android.permission.READ_CONTACTS" />
步骤⑤ 设计主界面监听以及适配,权限申请
MainActivity.java
package com.example.imagesproviderdemo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import org.w3c.dom.Text;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private Button btn_1,btn_2;
private List<Messageinfo>info;
/// 储存信息
private List<String> phonenumber;
/// 存储通讯录电话
private RadioGroup radioGroup;
Spinner spinner;
String check="";
/// 记录保存文本的格式
String checkI="";
/// 判断当前选择保存文本
private int flag = 0;
/// 标记位,0代表所有信息,1代表发送的信息,2代表接收的信息,3代表已存在通讯录电话的信息
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取控件
btn_1 = (Button) findViewById(R.id.btn_1);
btn_2 = (Button) findViewById(R.id.btn_2);
radioGroup = (RadioGroup)findViewById(R.id.radiogroup);
info = new ArrayList<Messageinfo>();
read_number(); /// 读取通讯录所有电话
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
//checkId就是当前选中的RadioButton,记录选中
check = checkedId==R.id.radiobutton1 ? "xml" : "txt";
}
});
spinner = (Spinner) findViewById(R.id.spinner1);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// 记录选中
checkI = (String) spinner.getSelectedItem();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
btn_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS)
!= PackageManager.PERMISSION_GRANTED) {//运行时权限处理
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{ Manifest.permission.READ_SMS }, 1);
} else {
/// 获取信息并显示
getMessage();
}
}
});
/// 备份信息 采用 SharedPreferences,在路径data/data/之下 记住他这个包名都是小写
btn_2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
/// 更新标记位并更新
if (checkI.equals("备份接收信息"))
{
flag = 1;
}
else if (checkI.equals("备份发送信息"))
{
flag = 2;
}
else if(checkI.equals("备份存在号码信息"))
{
flag = 3;
}
else
{
flag = 0;
}
/// 如果选择txt
if (check.equals("txt"))save_txt();
else save_xml();;
Toast.makeText(MainActivity.this,"备份成功",Toast.LENGTH_LONG).show();// toast长时间文本
}
});
}
public void read_number(){
/// 申请权限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{ Manifest.permission.READ_CONTACTS }, 0);
}
/// 直接查询
Cursor cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
phonenumber =new ArrayList<String>();
//向下移动光标
if (cursor != null) {
while(cursor.moveToNext()) {
/// 获取电话
String number = cursor.getString(cursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
phonenumber.add(number);
}
}
}
public void save_xml()
{
/// xml格式保存
SharedPreferences shared = getSharedPreferences("data",MODE_PRIVATE);
SharedPreferences.Editor editor = shared.edit();
editor.clear();
/// 由于前面的键不能同一个名字,所以才到后面加上一个i
for (int i=0;i<info.size();++i){
/// 不是想要的格式,丢弃
if (flag!=info.get(i).getFormatType())
{
/// 0的时候所有信息都保存
if (flag!=0)
continue;
}
if (flag==3)
/// 选择了3,就匹通讯录
{
boolean vis = true;
for (int j=0;j<phonenumber.size();++j)
{
if (phonenumber.get(j).equals(""+info.get(i).getFormatDate()))
{
vis = false;
break;
}
}
if (vis) continue;
}
editor.putString("number"+i,info.get(i).getAddress());
editor.putString("content"+i,info.get(i).getBody());
editor.putInt("type"+i,info.get(i).getFormatType() );
editor.putLong("time"+i,info.get(i).getFormatDate());
// System.out.println(info.get(i).getFormatDate());
}
editor.commit();///提交数据
}
public void save_txt()
{
FileOutputStream out = null;
BufferedWriter writer = null;
try {
/// 文件流储存
out = openFileOutput("data", Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
String Text="";
for (int i=0;i<info.size();++i)
{
if (flag!=info.get(i).getFormatType())
{
if (flag!=0)
continue;
}
if (flag==3)
{
boolean vis = true;
for (int j=0;j<phonenumber.size();++j)
{
if (phonenumber.get(j).equals(""+info.get(i).getFormatDate()))
{
vis = false;
break;
}
}
if (vis) continue;
}
Text += "手机号码:" + info.get(i).getAddress() + "\n";
Text += "短信内容:" + info.get(i).getBody() + "\n";
Text += "短信类型:" + info.get(i).getFormatType() + "\n";
Text += "短信发送时间:" + info.get(i).getFormatDate() + "\n\n";
}
writer.write(Text);
} catch (IOException e) {
e.printStackTrace();
} finally
{
try {
if (writer != null) {
writer.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
public void getMessage()
{
Uri uri = Uri.parse("content://sms/"); //获取系统信息的 uri
//获取 ContentResolver 对象
ContentResolver resolver = getContentResolver();
//通过 ContentResolver 对象查询系统短信
Cursor cursor = resolver.query(uri, new String[]{"_id", "address",
"body","type","date"}, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
// txt1.setVisibility(View.VISIBLE);/
if (info != null) info.clear();//清除集合中的数据
while (cursor.moveToNext()) {
int _id = cursor.getInt(0);
String address = cursor.getString(1);
String body = cursor.getString(2);
int type = cursor.getInt(3);
long date=cursor.getLong(4);
Messageinfo messinfo = new Messageinfo(_id, address, body,type,date);
info.add(messinfo);
}
ListView AlbumList = (ListView)findViewById(R.id.list_1);
/// 添加适配器
TextAdapter adapter = new TextAdapter(info,this);
AlbumList.setAdapter(adapter);
cursor.close();
}
}
/// 申请权限时会回调以下方法,故需要进行重写,申请成功权限和申请不成功的分支结果
@Override
public void onRequestPermissionsResult( int requestCode, @NonNull String[] permissions, @NonNull int[] grant)
{
super.onRequestPermissionsResult(requestCode,permissions,grant);
switch (requestCode) {
case 1:
if (grant.length > 0 && grant[0] == PackageManager.PERMISSION_GRANTED) {
getMessage();
} else {
Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
}
break;
case 0:
if (grant.length > 0 &&
grant[0] == PackageManager.PERMISSION_GRANTED) {
read_number();
} else {
Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
}