Huawei社、サムスンとトーストがポップアップしません通知許可を無効にした後、他のモデル
理由
次のようにソースコードのレビューはトースト、トースト表示がINotificationManagerクラスを通じて達成されることが判明し、通知が無効になっているとき、このような呼び出しが例外を返します後は、それが原因の通知を示していない、ソースコードは次のとおりです。
public void show() {
if (mNextView == null) {
throw new RuntimeException("setView must have been called");
}
INotificationManager service = getService();
String pkg = mContext.getOpPackageName();
TN tn = mTN;
tn.mNextView = mNextView;
try {
service.enqueueToast(pkg, tn, mDuration);
} catch (RemoteException e) {
// 权限禁用后走这里,这里是空方法,所以会发生既不crash又无响应的情况
}
}
これは、あなたが適切に実行することができますので、我々は、反射の仕方によってバイパスすることができ、かつ必要があります、バグのグーグル、キビ電話の書き換えトーストコードの一部である次のソリューションを:
ソリューション
public class ToastUtils {
private static Object iNotificationManagerObj;
/**
* @param context
* @param message
*/
public static void show(Context context, String message) {
show(context.getApplicationContext(), message, Toast.LENGTH_SHORT);
}
/**
* @param context
* @param message
*/
public static void show(Context context, String message, int duration) {
if (TextUtils.isEmpty(message)) {
return;
}
//后setText 兼容小米默认会显示app名称的问题
Toast toast = Toast.makeText(context, null, duration);
toast.setText(message);
if (isNotificationEnabled(context)) {
toast.show();
} else {
showSystemToast(toast);
}
}
/**
* 显示系统Toast
*/
private static void showSystemToast(Toast toast) {
try {
Method getServiceMethod = Toast.class.getDeclaredMethod("getService");
getServiceMethod.setAccessible(true);
//hook INotificationManager
if (iNotificationManagerObj == null) {
iNotificationManagerObj = getServiceMethod.invoke(null);
Class iNotificationManagerCls = Class.forName("android.app.INotificationManager");
Object iNotificationManagerProxy = Proxy.newProxyInstance(toast.getClass().getClassLoader(), new Class[]{iNotificationManagerCls}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//强制使用系统Toast
if ("enqueueToast".equals(method.getName())
|| "enqueueToastEx".equals(method.getName())) { //华为p20 pro上为enqueueToastEx
args[0] = "android";
}
return method.invoke(iNotificationManagerObj, args);
}
});
Field sServiceFiled = Toast.class.getDeclaredField("sService");
sServiceFiled.setAccessible(true);
sServiceFiled.set(null, iNotificationManagerProxy);
}
toast.show();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 消息通知是否开启
*
* @return
*/
private static boolean isNotificationEnabled(Context context) {
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
boolean areNotificationsEnabled = notificationManagerCompat.areNotificationsEnabled();
return areNotificationsEnabled;
}
}
同じ内容トースト短期ポップを繰り返すことはできません
理由
我々はクリックトーストを繰り返した場合、トーストは継続的に、たくさん、良いビジュアル体験をポップアップ表示されますので、インターネットの普及というこれらのソリューション:
Toast mToast;
public void showToast(String text) {
if (mToast == null) {
mToast = Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT);
} else {
mToast.setText(text);
mToast.setDuration(Toast.LENGTH_SHORT);
}
mToast.show();
}
この方法では、トーストは、表示されませんしながら、新しいバージョンが短時間表示されているアンドロイドの古いバージョンでも問題ありません。
同じテキストと、現在表示されているトースト、システムはその要求トースト現在の表示画面という、誤った操作と考えられています。
この問題は、不正なアプリはシステムの崩壊につながるインターフェース模倣システムトーストポップを持って防止するために行われると言われています。
ソリューション
これは、あなたがトーストをカスタマイズすることができ、この制限を周りを取得したい、とここで私はトーストのカスタムバージョンの神のgitのをお勧めしますシステムの制限です - XToast
https://github.com/getActivity/XToast
あなたがこの記事を気に入った場合、物品は、容易ではない、またはあなたが、私たちが助けるという希望をたくさん持って親指がアップし、前方に、関係します 。記事は、継続的に更新されます。絶対に乾燥!!!