标签: AlertDialog

AlertDialog禁止返回键

AlertDialog禁止返回键

android 如何让dialog不消失,即使是用户按了返回键dialog也不消失
解决的问题:软件提示升级的dialog时候,用户有可能按了返回键,但是现在的需求是用户只能按“确定升级”或者“暂时不升级”这两个按钮才能拿dialog消失,按返回键不能使dialog消失
方案:截取activity的 onkeydown事件,而应该截取dialog的key响应事件,当dialog在前台显示的时候,keylistener首先会派发到dialog里面,在那里面监听就行了。
先申明一个keylistener。
OnKeyListener keylistener = new DialogInterface.OnKeyListener(){
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode==KeyEvent.KEYCODE_BACK&&event.getRepeatCount()==0)
{
return true;
}
else
{
return false;
}
}
} ;
在把这个listener注册到dialog里面去 当初始化dialog的时候
builder.setTitle(getText(R.string.XXXX))
.setMessage(getText(R.XXXXXX))
.setOnKeyListener(key).setCancelable(false)
.setPositiveButton(android.R.string.ok, someOKButtonListener)
.setNegativeButton(android.R.string.cancel, null);

PS: setCancelable(false),作用是当dialog弹出来的时候,如果触点在dialog外围,按照默认的方式 dialog将消失。如果这个设为false的话 这种情况dialog就不会消失了。  加了这一句就OK了。dialog.setCancelable(false);

自定义Dialog或者AlertDialog在部分手机上margin失效的问题

*近项目中用到的自定义布局的Dialog比较多,我把宽度写死以后,在一些手机上是没有问题的,但是部分手机上(比如oppo手机)横向的margin不起作用,困扰了很长时间,今天有时间解决了一下。

原来不管是AlertDialog还是Dialog,因为AlertDialog集成于Dialog,他们本身的宽度都是与屏幕的宽度留有距离的,即我们在写自定义布局的时候不用给他设置成Dialog的样式,宽度match_parent,高度wrap_content即可,如果使用的是AlertDialog,ok,就不用管了,但是如果直接用的Dialog还是加上以下代码吧!

Window window=dialog.getWindow();
WindowManager.LayoutParams lp=window.getAttributes();
lp.width=WindowManager.LayoutParams.MATCH_PARENT;
lp.height=WindowManager.LayoutParams.WRAP_CONTENT;
window.setGravity(Gravity.CENTER);
window.setAttributes(lp);
总结:在部分手机上出现边距不起作用的应该是本来Dialog自身与屏幕宽度有边距,而我设置的宽度超出了它本身的宽度,导致margin不起作用。困惑了很久的问题终于豁然开朗了☺。

Android全局异常捕获并弹窗提示

Android 难免有崩溃的时候,但是崩溃了该如何处理呢?虽然那天有位同仁说 “既然崩溃了,用户体验就差了,心里会想这是毛APP,下次也不想用了” ,所以检查BUG以防崩溃是必须的,但是也需要一个后备方案,崩溃了能友好些,我们也能收集一些崩溃的信息。
说到全局捕获异常的UncaughtExceptionHandler,就不得不说期间遇到的各种坑:
1. 初始化肯定在Application,网上说的Activity启各种不认同。但在Application启就存在不能弹AlertDialog的问题(目前不确定,不知道是自己哪里没处理好还是的确是这个问题,有时间再验证一下)
2. 崩溃不一定是单次,在多层Activity中,崩溃一个顶层的Activity可能导致下层的Activity连续崩溃,所以uncaughtException可能会捕获到多次崩溃信息(具体影响后面会说到)
先来张崩溃后的效果图:
背景是另一个APP,当前的APP已崩溃并弹出该提示

%title插图%num
实现流程:
写个类继承于UncaughtExceptionHandler,实现方法
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处
mDefaultHandler.uncaughtException(thread, ex);
} else {
// 跳转到崩溃提示Activity
Intent intent = new Intent(mContext, CrashDialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
System.exit(0);// 关闭已奔溃的app进程
}
}

然后转handleException方法处理异常:
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}

// 收集错误信息
getCrashInfo(ex);

return true;
}

上面的代码很清楚了,如果异常被捕获到并且异常信息不会NULL,处理完则跳转到CrashDialog。为什么跳Activity用Dialog样式,而不直接弹AlertDialog,是因为的确弹不出来。
收集错误信息:
private void getCrashInfo(Throwable ex) {
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String errorMessage = writer.toString();
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String mFilePath = Environment.getExternalStorageDirectory() + “/” + App.ERROR_FILENAME;
FileTxt.WirteTxt(mFilePath, FileTxt.ReadTxt(mFilePath) + ‘\n’ + errorMessage);
} else {
Log.i(App.TAG, “哦豁,说好的SD呢…”);
}
}

是的,我把错误信息写到了存储并在刚才的CrashDialog中读取。为什么不直接传值呢?因为刚说到的坑第2条,多次崩溃的情况下,将导致直接传值只会传*后一次崩溃信息,而*后一次崩溃信息并不是主要引发崩溃的点,收集上来的错误信息可读性不大。那为什么我不写个全局变量来存储呢?因为尝试过,不知道是机型问题(Huawei Mate7 – API 23)还是全部问题,变量压根就不记录数据,*后只有将信息依次写到存储。
主要代码
App.java
package cn.qson.androidcrash;

/**
* @author x024
*/

import android.app.Application;

public class App extends Application {

public final static String TAG = “x024”;
public final static String ERROR_FILENAME = “x024_error.log”;

@Override
public void onCreate() {
super.onCreate();

CrashHanlder.getInstance().init(this);

}
}

CrashHanlder.java
package cn.qson.androidcrash;

/**
* @author x024
*/

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;

import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.util.Log;

/**
* 收集错误报告并上传到服务器
*
* @author x024
*
*/
public class CrashHanlder implements UncaughtExceptionHandler {
private Thread.UncaughtExceptionHandler mDefaultHandler;
// CrashHandler实例
private static CrashHanlder INSTANCE = new CrashHanlder();
// 程序的Context对象
private Context mContext;

private CrashHanlder() {
}

public static CrashHanlder getInstance() {
return INSTANCE;
}

/**
* 初始化
*
* @param context
*/
public void init(Context context) {
mContext = context;
// 获取系统默认的UncaughtException处理
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 设置该CrashHandler为程序的默认处理
Thread.setDefaultUncaughtExceptionHandler(this);
}

/**
* 异常捕获
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处
mDefaultHandler.uncaughtException(thread, ex);
} else {
// 跳转到崩溃提示Activity
Intent intent = new Intent(mContext, CrashDialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
System.exit(0);// 关闭已奔溃的app进程
}
}

/**
* 自定义错误捕获
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false.
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}

// 收集错误信息
getCrashInfo(ex);

return true;
}

/**
* 收集错误信息
*
* @param ex
*/
private void getCrashInfo(Throwable ex) {
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String errorMessage = writer.toString();
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String mFilePath = Environment.getExternalStorageDirectory() + “/” + App.ERROR_FILENAME;
FileTxt.WirteTxt(mFilePath, FileTxt.ReadTxt(mFilePath) + ‘\n’ + errorMessage);
} else {
Log.i(App.TAG, “哦豁,说好的SD呢…”);
}

}

}

CrashDialog.java
package cn.qson.androidcrash;

/**
* @author x024
*/

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class CrashDialog extends Activity {

private String mFilePath;
private Button btnExit, btnRestart;
private Boolean StorageState = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crash);
CrashDialog.this.setFinishOnTouchOutside(false);
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
mFilePath = Environment.getExternalStorageDirectory() + “/” + App.ERROR_FILENAME;
StorageState = true;
} else {
Log.i(App.TAG, “哦豁,说好的SD呢…”);
}

new Thread(upLog).start();
initView();
}

private void initView() {
btnExit = (Button) findViewById(R.id.cash_exit);
btnRestart = (Button) findViewById(R.id.cash_restart);

btnExit.setOnClickListener(mOnClick);
btnRestart.setOnClickListener(mOnClick);

}

OnClickListener mOnClick = new OnClickListener() {

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.cash_exit:
exit();
break;
case R.id.cash_restart:
restart();
break;
default:
break;
}
}
};

// 上传错误信息
Runnable upLog = new Runnable() {
@Override
public void run() {
try {

String Mobile = Build.MODEL;
String maxMemory = “” + getmem_TOLAL() / 1024 + “m”;
String nowMemory = “” + getmem_UNUSED(CrashDialog.this) / 1024 + “m”;
String eMessage = “未获取到错误信息”;
if (StorageState) {
eMessage = FileTxt.ReadTxt(mFilePath).replace(“‘”, “”);
}
Log.i(App.TAG, “Mobile:” + Mobile + ” | maxMemory:” + maxMemory + ” |nowMemory:” + nowMemory
+ ” |eMessage:” + eMessage);

/**
* 可以在这调你自己的接口上传信息
*/
} catch (Exception e) {
e.printStackTrace();
}
}
};

private void exit() {
FileTxt.deleteFile(mFilePath);
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
}

private void restart() {
Intent intent = getBaseContext().getPackageManager()
.getLaunchIntentForPackage(getBaseContext().getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
exit();
}

@Override
public void onBackPressed() {
super.onBackPressed();
exit();
}

// 获取可用内存
public static long getmem_UNUSED(Context mContext) {
long MEM_UNUSED;
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
am.getMemoryInfo(mi);

MEM_UNUSED = mi.availMem / 1024;
return MEM_UNUSED;
}

// 获取剩余内存
public static long getmem_TOLAL() {
long mTotal;
String path = “/proc/meminfo”;
String content = null;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(path), 8);
String line;
if ((line = br.readLine()) != null) {
content = line;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
int begin = content.indexOf(‘:’);
int end = content.indexOf(‘k’);

content = content.substring(begin + 1, end).trim();
mTotal = Integer.parseInt(content);
return mTotal;
}

}

完整代码:http://download.csdn.net/detail/hx7013/9710757

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速