android studio版本:2021.2.1
例程名称:pravicydialog
功能:
1、启动app后弹窗隐私协议
2、屏蔽返回键
3、再次启动不再显示隐私协议。
本例程的绝大部分代码来自下面链接,因为本人改了一些,增加了一些功能,所以不有脸的算原创了。
下面这个例子是“正宗”app隐私协议实现方法,而且协议内容使用的是txt格式文件,据说如果使用html格式文件,各大平台在审核的时候大概率无法通过,但协议内容的还应该有更详细协议及说明的链接,我没做,暂时还没学会,会了再修改一下。
Android 实现隐私政策提示弹窗
对原作者表示感谢!
直接上代码:
MainActivity.java
/* | |
完成日期:年1月28日 | |
功能:app协议页、打开app弹出协议,禁止返回键取消显示。 | |
、再次打开协议页不再弹出。 | |
*/ | |
package com.example.pravicydialog; | |
import androidx.appcompat.app.AppCompatActivity; | |
import android.app.AlertDialog; | |
import android.app.Dialog; | |
import android.content.Context; | |
import android.os.Bundle; | |
import android.util.DisplayMetrics; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.WindowManager; | |
import android.widget.TextView; | |
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.io.UnsupportedEncodingException; | |
public class MainActivity extends AppCompatActivity { | |
Dialog dialog; | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
PravicyCheck(); | |
} | |
public void onClickAgree(View v) | |
{ | |
dialog.dismiss(); | |
//下面将已阅读标志写入文件,再次启动的时候判断是否显示。 | |
this.getSharedPreferences("file", Context.MODE_PRIVATE).edit() | |
.putBoolean("AGREE", true) | |
.apply(); | |
} | |
public void onClickDisagree(View v) | |
{ | |
System.exit();//退出软件 | |
} | |
public void showPrivacy(String privacyFileName){ | |
String str = initAssets(privacyFileName); | |
final View inflate = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_privacy_show, null); | |
TextView tv_title = (TextView) inflate.findViewById(R.id.tv_title); | |
tv_title.setText("隐私政策授权提示"); | |
TextView tv_content = (TextView) inflate.findViewById(R.id.tv_content); | |
tv_content.setText(str); | |
dialog = new AlertDialog | |
.Builder(MainActivity.this) | |
.setView(inflate) | |
.show(); | |
// 通过WindowManager获取 | |
DisplayMetrics dm = new DisplayMetrics(); | |
getWindowManager().getDefaultDisplay().getMetrics(dm); | |
final WindowManager.LayoutParams params = dialog.getWindow().getAttributes(); | |
params.width = dm.widthPixels*/5; | |
params.height = dm.heightPixels*/2; | |
dialog.setCancelable(false);//屏蔽返回键 | |
dialog.getWindow().setAttributes(params); | |
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); | |
} | |
/** | |
* 从assets下的txt文件中读取数据 | |
*/ | |
public String initAssets(String fileName) { | |
String str = null; | |
try { | |
InputStream inputStream = getAssets().open(fileName); | |
str = getString(inputStream); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return str; | |
} | |
public static String getString(InputStream inputStream) { | |
InputStreamReader inputStreamReader = null; | |
try { | |
inputStreamReader = new InputStreamReader(inputStream, "UTF-"); | |
} catch (UnsupportedEncodingException e) { | |
e.printStackTrace(); | |
} | |
BufferedReader reader = new BufferedReader(inputStreamReader); | |
StringBuffer sb = new StringBuffer(""); | |
String line; | |
try { | |
while ((line = reader.readLine()) != null) { | |
sb.append(line); | |
sb.append("\n"); | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return sb.toString(); | |
} | |
public void PravicyCheck(){ | |
Boolean status =this.getSharedPreferences("file",Context.MODE_PRIVATE) | |
.getBoolean("AGREE",false); | |
if (status==true){ | |
}else{ | |
showPrivacy("privacy.txt");//放在assets目录下的隐私政策文本文件 | |
} | |
} | |
} |
说明:
1、dialog.setCancelable(false);屏蔽返回键
2、将已阅读标志写入文件,再次启动的时候判断是否显示。
preferences用法见,实现不同,原理一样:分享一个SharedPreferences的工具类,方便保存数据
this.getSharedPreferences("file", Context.MODE_PRIVATE).edit() | |
.putBoolean("AGREE", true) | |
.apply(); |
3、判断是否是第一次启动代码块:
public void PravicyCheck(){ | |
//读标志 | |
Boolean status =this.getSharedPreferences("file",Context.MODE_PRIVATE) | |
.getBoolean("AGREE",false); | |
if (status==true){ | |
//如果status为true,不显示对话框,直接进主页面。 | |
}else{ | |
//如果status不为true显示对话框 | |
showPrivacy("privacy.txt");//放在assets目录下的隐私政策文本文件 | |
} |
activity_main.xml(这个是主页面,可以什么都不放,我放了一个textview)
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="horizontal"> | |
<TextView | |
android:id="@+id/textView" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="欢迎使用本app!!" | |
android:textColor="#EE63" | |
android:textSize="sp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> |
dialog_privacy_show.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:background="@drawable/dialog_privacy_shape" | |
android:orientation="vertical"> | |
<RelativeLayout | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_above="@+id/ll_btn_bottom" | |
android:layout_marginBottom="dp" | |
android:gravity="center" | |
android:orientation="vertical"> | |
<TextView | |
android:id="@+id/tv_title" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="dp" | |
android:layout_marginBottom="dp" | |
android:text="隐私政策授权提示" | |
android:textColor="#" | |
android:textSize="sp" /> | |
<ScrollView | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_marginLeft="dp" | |
android:layout_marginRight="dp" | |
android:fadingEdgeLength="dp" | |
android:requiresFadingEdge="horizontal"> | |
<TextView | |
android:id="@+id/tv_content" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_marginTop="dp" | |
android:singleLine="false" | |
android:text="" | |
android:textColor="#" /> | |
</ScrollView> | |
</LinearLayout> | |
<LinearLayout | |
android:id="@+id/ll_btn_bottom" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_alignParentBottom="true" | |
android:gravity="center" | |
> | |
<Button | |
android:id="@+id/btn_agree" | |
android:layout_width="dp" | |
android:layout_height="wrap_content" | |
android:layout_marginBottom="dp" | |
android:layout_marginRight="dp" | |
android:text="同意" | |
android:onClick="onClickAgree" | |
android:textColor="#FF" | |
android:background="@drawable/button_shape"/> | |
<Button | |
android:id="@+id/btn_disagree" | |
android:layout_width="dp" | |
android:layout_marginBottom="dp" | |
android:layout_height="wrap_content" | |
android:text="放弃使用" | |
android:onClick="onClickDisagree" | |
android:textColor="#" | |
android:background="@drawable/button_shape"/> | |
</LinearLayout> | |
</RelativeLayout> | |
</LinearLayout> |
button_shape.xml(按钮形状等属性)
<!--相当于做了一张圆角的图片,然后给button作为背景图片--> | |
<shape xmlns:android="http://schemas.android.com/apk/res/android" | |
android:shape="rectangle"> | |
<!--设置背景色--> | |
<solid android:color="#FE27" /> | |
<!--设置圆角--> | |
<corners android:radius="dip" /> | |
<padding | |
android:bottom="dp" | |
android:left="dp" | |
android:right="dp" | |
android:top="dp"> | |
</padding> | |
</shape> |
dialog_privacy_shape.xml(对话框属性)
<shape xmlns:android="http://schemas.android.com/apk/res/android" | |
android:shape="rectangle"> | |
<!-- 填充色 --> | |
<solid android:color="#ffffff" /> | |
<!-- 矩形圆角半径 --> | |
<corners android:radius="dp" /> | |
</shape> |
各个文件位置如图:
最后动图: