前言:
? ? ? ? 现在都比较注重隐私信息了,所以很经常碰到要添加隐私协议弹窗。对于一些偷懒技术来说,有个现成的代码或封装好的东西,就是最省事的。没必要花过多的时间去处理。
? ? ? ? 嗯,本菜鸟也偷懒,就不直接封装了,直接把对应的代码放上,需要的直接把对应的代码拷贝到自己工程项目中,然后调用使用就可以了,省事。
1.肯定是少不了隐私弹窗的界面啦。所以,在layout目录下创建一个界面。
? ?本菜鸟起的名字就是activity_privacy_policy.xml,你们用什么自己喜欢呗。
? ? 直接上activity_privacy_policy的代码。
<?xml version="1.0" encoding="utf-8"?>
<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"
android:background="@drawable/dialog_privacy_bg"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/ll_btn_bottom"
android:layout_marginBottom="35dp"
android:gravity="center"
android:orientation="vertical"
tools:ignore="UnknownId">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="用户使用协议"
android:textColor="@color/colorBlack"
android:textSize="18sp"
/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="15dp"
android:fadingEdgeLength="60dp"
android:requiresFadingEdge="horizontal">
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:singleLine="false"
android:text=""
android:textColor="@color/colorBlack"
/>
</ScrollView>
</LinearLayout>
<LinearLayout
android:id="@+id/BtnView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:gravity="bottom">
<Button
android:id="@+id/btn_exit"
android:layout_width="0dp"
android:layout_height="32dp"
android:layout_weight="1"
android:background="@color/colorWhite"
android:text="@string/privacy_exit"
android:textColor="@color/colorGray"
android:textSize="16sp"
android:textStyle="bold" />
<View
android:layout_width="0.25dp"
android:layout_height="40dp"
android:background="@color/colorGray" />
<Button
android:id="@+id/btn_enter"
android:layout_width="0dp"
android:layout_height="32dp"
android:layout_weight="1"
android:background="@color/colorWhite"
android:text="@string/privacy_agree"
android:textColor="@color/colorOrange"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
2.既然有弹出界面,那就有弹出界面的bg代码,所以在drawable目录下创建一个dialog_privacy_bg.xml。
代码:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!--填充设置-->
<solid android:color="@android:color/white" />
<!--圆角设置-->
<corners android:radius="6dp" />
</shape>
3.然后少不了颜色设置啦。直接上在values目录下的colors.xml里面补上填充颜色。例如本菜鸟所用到的颜色
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<color name="colorWhite">#FFFFFFFF</color>
<color name="colorBlack">#FF000000</color>
<color name="colorGray">#878787</color>
<color name="colorOrange">#FFE26C25</color>
<color name="colorBlue">#FF036EB8</color>
</resources>
4.颜色有了,少不了文字嘛。所以在values目录下的strings.xml里面按钮文字之类的。本菜鸟用
<string name="privacy_exit">退出</string>
<string name="privacy_agree">同意</string>
这两个作为确定和拒绝隐私内容的按钮文字,你们喜欢用什么自己确定嘛。毕竟,我不可能逼你要用和我一样的。
5.实现隐私弹窗的前提内容已经准备好了,那就少不了开始调用隐私弹窗的了,隐私内容毕竟是第一次进入的时候需要的,那就少不了根据实际情况做处理,其次隐私一般都有两个,一个是用户协议,一个是隐私协议。所以,那个前那个后,看需求啦,
? 5.1既然只需要显示一次的,那就需要保存数据,直接上保存数据工具类。
package //包名我就隐藏了
import android.content.Context;
import android.content.SharedPreferences;
import java.util.Map;
/**
* 数据缓存到本地
* **/
public class DataUtils {
/**
* 保存在手机里的SP文件名
*/
public static final String FILE_NAME = "privacy_sp";
/**
* 保存数据
*/
public static void put(Context context, String key, Object obj) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (obj instanceof Boolean) {
editor.putBoolean(key, (Boolean) obj);
} else if (obj instanceof Float) {
editor.putFloat(key, (Float) obj);
} else if (obj instanceof Integer) {
editor.putInt(key, (Integer) obj);
} else if (obj instanceof Long) {
editor.putLong(key, (Long) obj);
} else {
editor.putString(key, (String) obj);
}
editor.commit();
}
public static boolean isKeep(Context context, String key, Object defaultObj){
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
if(sp.contains(key))
{
}
return false;
}
/**
* 获取指定数据
*/
@org.jetbrains.annotations.Nullable
public static Object get(Context context, String key, Object defaultObj) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
if (defaultObj instanceof Boolean) {
return sp.getBoolean(key, (Boolean) defaultObj);
} else if (defaultObj instanceof Float) {
return sp.getFloat(key, (Float) defaultObj);
} else if (defaultObj instanceof Integer) {
return sp.getInt(key, (Integer) defaultObj);
} else if (defaultObj instanceof Long) {
return sp.getLong(key, (Long) defaultObj);
} else if (defaultObj instanceof String) {
return sp.getString(key, (String) defaultObj);
}
return null;
}
/**
* 删除指定数据
*/
public static void remove(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
editor.commit();
}
/**
* 返回所有键值对
*/
public static Map<String, ?> getAll(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
Map<String, ?> map = sp.getAll();
return map;
}
/**
* 删除所有数据
*/
public static void clear(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
editor.commit();
}
/**
* 检查key对应的数据是否存在
*/
public static boolean contains(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
return sp.contains(key);
}
}
5.2保存数据类有了,那就开干弄隐私界面代码,毕竟本菜鸟没有封装,所以就直接上用到的隐私弹窗代码。使用的时候,可以自己进行封装一下,也可以直接扔到Activity类里面。
1.既然是保存第一次数据的。所以,执行调用隐私前,必须拿到是否同意哪个隐私内容了。
String isPrivacy = DataUtils.get(MainActivity.this,"privacy","0").toString();
String isPolicy = DataUtils.get(MainActivity.this,"policy","0").toString();
2.有两个隐私,那就需要在全局定义一个变量来确保当前属于那个隐私的
/**当前表现的隐私类型:
* 1:个人信息隐私
* 2:使用条款
* **/
private int prviacyType = 1;
注意:一个是用户协议记录状态,一个是隐私协议记录状态。至于那个,你们自己定也可以看我的。
3.拿到状态后,就判断弹出那个协议界面了。
//没有同意隐私条约的,则弹出隐私条约
if(isPrivacy.equals("1") && isPolicy.equals("1"))
{
//都同意了,直接跳过隐私弹窗处理
}else if(isPrivacy.equals("0"))
{
prviacyType = 1;
showPrivacy("privacy.txt","个人信息隐私");
}else if(isPrivacy.equals("1")&& isPolicy.equals("0"))
{
prviacyType = 2;
showPrivacy("policy.txt","使用条款");
}
4.前置内容都设定了,那就开始调用弹出隐私,并且根据调用的隐私内容去加载隐私内容回来并且展示出来。
public void showPrivacy(String privacyFileName,String title) {
//加载当前要显示的隐私内容文本
String str = initAssets(privacyFileName);
//布局ui界面信息
final View inflate = LayoutInflater.from(this).inflate(R.layout.activity_privacy_policy, null);
TextView tv_title = (TextView) inflate.findViewById(R.id.tv_title);
//设置隐私内容抬头
tv_title.setText(title);
//显示隐私内容,因为文本布局,需要美观,所以内容用需要使用换行符,但加载回来的内容用\n的话无法真正做到换行,只能在文本中用<br/>作为换行符,然后进行替换成\n
TextView tv_content = (TextView) inflate.findViewById(R.id.tv_content);
tv_content.setText(str.replace("<br/>", "\n"));
//获取同意和退出两个按钮并且添加事件
TextView btn_exit = (TextView) inflate.findViewById(R.id.btn_exit);
TextView btn_enter = (TextView) inflate.findViewById(R.id.btn_enter);
//开始弹出隐私界面
final Dialog dialog = new AlertDialog
.Builder(this)
.setView(inflate)
.show();
//对话框弹出后点击或按返回键不消失
dialog.setCancelable(false);
WindowManager m = getWindowManager();
Display defaultDisplay = m.getDefaultDisplay();
final WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
params.width = (int) (defaultDisplay.getWidth() * 0.90);
dialog.getWindow().setAttributes(params);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
//退出按钮事件
btn_exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
finish();
}
});
//同意按钮事件
btn_enter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
if(prviacyType == 1)
{
prviacyType = 2;
//保存隐私同意状态
DataUtils.put(MainActivity.this,"privacy","1");
//显示下一个隐私内容
showPrivacy("policy.txt","使用条款");
}else if(prviacyType == 2)
{
DataUtils.put(MainActivity.this,"policy","1");
//两个隐私内容都确定后,开始执行下一步
}
}
});
}
/**
* 从assets下的txt文件中读取数据
*/
public String initAssets(String fileName) {
String str = null;
try {
InputStream inputStream = getAssets().open(fileName);
str = getString(inputStream);
} catch (IOException e1) {
e1.printStackTrace();
}
return str;
}
public static String getString(InputStream inputStream) {
InputStreamReader inputStreamReader = null;
try {
inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
BufferedReader reader = new BufferedReader(inputStreamReader);
StringBuffer sb = new StringBuffer("");
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("");
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
结束:
? ? ? ? 至此隐私弹窗就已经处理好了。隐私文本内容就不提供了,这些每一家的都不一样的。具体叫提供隐私的相关人员提供即可。
? ? ? ? 注意事项:本菜鸟在弄的时候遇到的坑
? ? ? ? 1.文本编码问题。所以隐私为txt文本格式,但一定要处理编码,要不读取回来的隐私内容为乱码。
? ? ? ? 2.文本换行问题,隐私内容不可能没有段落之类的,如果直接不加任何换行符进去,加载回来的内容不换行的,但如果使用\n作为换行符,在文本窗口里面展示根本无法与自己想象的一致,所以直接采取<br>作为换行符。在隐私文本中,根据自己美观需求,在每一段落后加一个或多个。然后在加载回来后,用\n替换<br/>实现换行。
? ? ? ? 3.隐私弹窗的界面大小,需要根据自己实际情况而定,毕竟需要美观又不是全屏覆盖。所以,大家都懂的,虽然流传着技术的美观就是一坨屎,但能好看点就弄好看点嘛。起码自己看的过去。
|