精华内容
下载资源
问答
  • 一键禁用系统APP.7z

    2021-01-06 10:20:07
    三星一键禁用软件 pdp
  • 1、禁用APP adb shell pm disable-user '包名' 2、启动APP adb shell pm enable '包名'

    1、禁用APP

    adb shell pm disable-user '包名'

    2、解禁APP

    adb shell pm enable '包名'

    3、指定连接设备

    adb -s 设备名 shell

    4、安装apk

    adb install 包名---

    说明install后可加-r -t -s -d -p等关键字

    -r:替换已存在应用

    -t:测试package标识

    -s:将应用安装到adcard

    -d:忽略版本号

    -p:部分安装apk标志

    5、卸载应用

    adb uninstall 包名

    6、卸载APP,但保存数据和缓存文件

    adb uninstall -k 包名

    7、adb 命令更改日期

    adb shell date 0822216202021.00

    7、查看手机所有包名

    adb shell pm list packages

    8、查看所有三方APP包名

    adb shell pm list packages -3

    9、清除应用数据和缓存信息

    adb shell pm clear 包名

    10、adb 命令修改时间

    adb root;adb shell date 080816202021.00

    11、 将手机卡中的某个文件复制到电脑

    输入: adb pull 手机存储路径  电脑路径

    12、从电脑端向手机复制文件

    输入: adb push 电脑路径  手机存储路径  

    13、repo 更新代码

    repo sync -d --prune --force-sync --no-tags -f -j6

    展开全文
  • 一个防沉迷的App,远离手机
  • Android8.0中实现APP禁用模式(

    千次阅读 2019-03-16 11:24:38
    一个已安装的应用被设置为禁用的时候,在启动器中,APP图标灰色,且APP不能启动。 需求分析 打开一个APP的方式有三种:1、从启动器点击图标启动;2、点击APP弹出的通知启动;3、点击多任务键,选择APP。这三种...

    需求

    产品经理要求在Android平板中实现一个应用的禁用模式。当一个已安装的应用被设置为禁用的时候,在启动器中,APP图标灰色,且APP不能启动。

    需求分析

    打开一个APP的方式有三种:1、从启动器点击图标启动;2、点击APP弹出的通知启动;3、点击多任务键,选择APP。这三种启动方式中,第一个很容易实现禁用,只需要修改launcher就行,在图标的点击事件处理中增加一点逻辑即可。这里就分析一下如何在第二种和第三种启动方式中实现禁用模式。

    数据传递

    哪个APP被禁用是APP设置的,所以禁用信息要从APP传递到framework中。这个信息不仅要能get到,而且要能实时的监听。要做到这种跨进程的数据传递,做好的方式就是通过ContentProvider。

    NotificationManagerService

    Android中发送通知的方法在NotificationManager中,所以我们从NotificationManager开始找代码。NotificationManager中的notify方法有如下三个

    public void notify(int id, Notification notification)
    {
        notify(null, id, notification);
    }
    
    public void notify(String tag, int id, Notification notification)
    {
        notifyAsUser(tag, id, notification, new UserHandle(UserHandle.myUserId()));
    }
    
    public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
    {
        INotificationManager service = getService();
        String pkg = mContext.getPackageName();
        // Fix the notification as best we can.
        Notification.addFieldsFromContext(mContext, notification);
        if (notification.sound != null) {
            notification.sound = notification.sound.getCanonicalUri();
            if (StrictMode.vmFileUriExposureEnabled()) {
                notification.sound.checkFileUriExposed("Notification.sound");
            }
        }
        fixLegacySmallIcon(notification, pkg);
        if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
            if (notification.getSmallIcon() == null) {
                throw new IllegalArgumentException("Invalid notification (no valid small icon): "
                        + notification);
            }
        }
        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
        notification.reduceImageSizes(mContext);
        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        boolean isLowRam = am.isLowRamDevice();
        final Notification copy = Builder.maybeCloneStrippedForDelivery(notification, isLowRam);
        // 关键在这里
        try {
            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                    copy, user.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    

    可以看到,这三个方法实际上最终都调用到了notifyAsUser方法中。这个方法的前面是一些参数的检查,关键的内容是下面这行:

    service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id, copy, user.getIdentifier());
    

    service的类型是INotificationManager接口,熟悉Framework的朋友都知道,这是一个aidl接口,其实现就是xxxService。这里就是NotificationManagerService。下面就看下NotificationManagerService的enqueueNotificationWithTag方法。

    @Override
    public void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
            Notification notification, int userId) throws RemoteException {
        enqueueNotificationInternal(pkg, opPkg, Binder.getCallingUid(),
                Binder.getCallingPid(), tag, id, notification, userId);
    }
    

    这里实际调用了enqueueNotificationInternal方法。这种xxxInternal的函数命名方式也是Android的常规操作了。

    void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
    		final int callingPid, final String tag, final int id, final Notification notification,
    		int incomingUserId) {
    	if (DBG) {
    		Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
    				+ " notification=" + notification);
    	}
    	checkCallerIsSystemOrSameApp(pkg);
    
    	final int userId = ActivityManager.handleIncomingUser(callingPid,
    			callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
    	final UserHandle user = new UserHandle(userId);
    
    	if (pkg == null || notification == null) {
    		throw new IllegalArgumentException("null not allowed: pkg=" + pkg
    				+ " id=" + id + " notification=" + notification);
    	}
    
    	// The system can post notifications for any package, let us resolve that.
    	final int notificationUid = resolveNotificationUid(opPkg, callingUid, userId);
    
    	// Fix the notification as best we can.
    	try {
    		final ApplicationInfo ai = mPackageManagerClient.getApplicationInfoAsUser(
    				pkg, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
    				(userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
    		Notification.addFieldsFromContext(ai, notification);
    
    		int canColorize = mPackageManagerClient.checkPermission(
    				android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg);
    		if (canColorize == PERMISSION_GRANTED) {
    			notification.flags |= Notification.FLAG_CAN_COLORIZE;
    		} else {
    			notification.flags &= ~Notification.FLAG_CAN_COLORIZE;
    		}
    
    	} catch (NameNotFoundException e) {
    		Slog.e(TAG, "Cannot create a context for sending app", e);
    		return;
    	}
    
    	mUsageStats.registerEnqueuedByApp(pkg);
    
    	// setup local book-keeping
    	String channelId = notification.getChannelId();
    	if (mIsTelevision && (new Notification.TvExtender(notification)).getChannelId() != null) {
    		channelId = (new Notification.TvExtender(notification)).getChannelId();
    	}
    	final NotificationChannel channel = mRankingHelper.getNotificationChannel(pkg,
    			notificationUid, channelId, false /* includeDeleted */);
    	if (channel == null) {
    		final String noChannelStr = "No Channel found for "
    				+ "pkg=" + pkg
    				+ ", channelId=" + channelId
    				+ ", id=" + id
    				+ ", tag=" + tag
    				+ ", opPkg=" + opPkg
    				+ ", callingUid=" + callingUid
    				+ ", userId=" + userId
    				+ ", incomingUserId=" + incomingUserId
    				+ ", notificationUid=" + notificationUid
    				+ ", notification=" + notification;
    		Log.e(TAG, noChannelStr);
    		doChannelWarningToast("Developer warning for package \"" + pkg + "\"\n" +
    				"Failed to post notification on channel \"" + channelId + "\"\n" +
    				"See log for more details");
    		return;
    	}
    
    	final StatusBarNotification n = new StatusBarNotification(
    			pkg, opPkg, id, tag, notificationUid, callingPid, notification,
    			user, null, System.currentTimeMillis());
    	final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
    
    	if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0
    			&& (channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
    			&& (r.getImportance() == IMPORTANCE_MIN || r.getImportance() == IMPORTANCE_NONE)) {
    		// Increase the importance of foreground service notifications unless the user had an
    		// opinion otherwise
    		if (TextUtils.isEmpty(channelId)
    				|| NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
    			r.setImportance(IMPORTANCE_LOW, "Bumped for foreground service");
    		} else {
    			channel.setImportance(IMPORTANCE_LOW);
    			mRankingHelper.updateNotificationChannel(pkg, notificationUid, channel, false);
    			r.updateNotificationChannel(channel);
    		}
    	}
    
    	if (!checkDisqualifyingFeatures(userId, notificationUid, id, tag, r,
    			r.sbn.getOverrideGroupKey() != null)) {
    		return;
    	}
    
    	// Whitelist pending intents.
    	if (notification.allPendingIntents != null) {
    		final int intentCount = notification.allPendingIntents.size();
    		if (intentCount > 0) {
    			final ActivityManagerInternal am = LocalServices
    					.getService(ActivityManagerInternal.class);
    			final long duration = LocalServices.getService(
    					DeviceIdleController.LocalService.class).getNotificationWhitelistDuration();
    			for (int i = 0; i < intentCount; i++) {
    				PendingIntent pendingIntent = notification.allPendingIntents.valueAt(i);
    				if (pendingIntent != null) {
    					am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(),
    							WHITELIST_TOKEN, duration);
    				}
    			}
    		}
    	}
    
    	mHandler.post(new EnqueueNotificationRunnable(userId, r));
    }
    

    这个函数虽然很长,但是只要静下心来看一下,会发现有用的没几行(其实只有4行)。

    if (DBG) {
    	Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
    			+ " notification=" + notification);
    }
    

    函数最开头的这4行,给了我们重要的信息:包名。包名是直接从NotificationManager中传过来的,所以我们可以在这里对包名进行过滤,发现是被禁用掉的包名就直接返回。这个函数的返回值类型是void,直接返回也不会有其他的影响。
    我们把过滤的逻辑就加在这个打印日志行的下面,实际上,就是在NotificationManagerService在处理应用发送通知的一开头就进行过滤,这样对其内部逻辑的影响最小,避免Service内部的状态被我们加的代码搞乱。

    好的,改到这里,被禁用的APP就不能发送新的通知了。那么,在被禁用之前发送的通知怎么办呢?用户点击之后还是可以进入啊?所以,在通过ContentProvider监听到禁用APP的名单发生变化之后,要在onChange函数里面,把已经用的APP的所有通知全部清除掉。下面我们来看看NotificationManager中的清除通知的函数。

    /**
     * Cancel a previously shown notification.  If it's transient, the view
     * will be hidden.  If it's persistent, it will be removed from the status
     * bar.
     */
    public void cancel(int id)
    {
        cancel(null, id);
    }
    
    /**
     * Cancel a previously shown notification.  If it's transient, the view
     * will be hidden.  If it's persistent, it will be removed from the status
     * bar.
     */
    public void cancel(String tag, int id)
    {
        cancelAsUser(tag, id, new UserHandle(UserHandle.myUserId()));
    }
    
    /**
     * @hide
     */
    public void cancelAsUser(String tag, int id, UserHandle user)
    {
        INotificationManager service = getService();
        String pkg = mContext.getPackageName();
        if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
        try {
            service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    
    /**
     * Cancel all previously shown notifications. See {@link #cancel} for the
     * detailed behavior.
     */
    public void cancelAll()
    {
        INotificationManager service = getService();
        String pkg = mContext.getPackageName();
        if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
        try {
            service.cancelAllNotifications(pkg, UserHandle.myUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    

    前2个函数最终都调用到了cancelAsUser,它和cancelAll的区别就是后者会把当前应用发的所有通知都清除掉。所以,看这个就好了。这里调用到了NotificationManagerService的cancelAllNotifications函数。

    @Override
    public void cancelAllNotifications(String pkg, int userId) {
        checkCallerIsSystemOrSameApp(pkg);
    
        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                Binder.getCallingUid(), userId, true, false, "cancelAllNotifications", pkg);
    
        // Calling from user space, don't allow the canceling of actively
        // running foreground services.
        cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
                pkg, null, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId,
                REASON_APP_CANCEL_ALL, null);
    }
    

    这个函数就是通过cancelAllNotificationsInt这个函数,清除掉指定包名的所有通知。因为这个函数时实现的INotificationManager.Stub,所以,我们在NotificationObserver里面调用不到,所以,我们仿照这个函数的写法,调用cancelAllNotificationsInt函数。我们看一下cancelAllNotificationsInt函数的定义:

    **
     * Cancels a notification ONLY if it has all of the {@code mustHaveFlags}
     * and none of the {@code mustNotHaveFlags}.
     */
    void cancelNotification(final int callingUid, final int callingPid,
            final String pkg, final String tag, final int id,
            final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete,
            final int userId, final int reason, final ManagedServiceInfo listener) {
            ...
            }
    

    这个函数里面有两个flag:mustHaveFlags和mustNotHaveFlags。从函数注释看出,这个函数清除的通知必须包含所有的mustHaveFlags,同时mustNotHaveFlag必须一个都没有。那么,对我们来说,我们要清除的是指定应用的所有通知,不要这么多的限制条件。所以,这两个flag传0即可。

    cancelAllNotificationsInt(Binder.getCallingUid(),
                                Binder.getCallingPid(),
                                pkg,
                                null,
                                0,
                                0,
                                true,
                                UserHandle.myUserId(),
                                REASON_APP_CANCEL_ALL,
                                null);
    
    展开全文
  • WhatsApp Web的隐形模式 这是chrome扩展程序的源代码,该扩展程序在WhatsApp Web上禁用已读回执和状态更新。 您可以在找到原始扩展名。 直接从GitHub安装 要在店外安装扩展程序,请从“页面以zip文件的形式... 还有一个
  • {"status":240,"message":"APP 服务被禁用"}; 百度给出的结论是自己创建AK时的设置有问题,实际检查设置没有问题; ![在这里插入图片描述]...

    使用百度地图API进行逆地理编码时发现将新建的服务端AK填入到URL中进行访问时返回
    {“status”:240,“message”:“APP 服务被禁用”};
    百度给出的结论是自己创建AK时的设置有问题,实际检查设置没有问题;
    在这里插入图片描述
    提交工单得到的反馈结果
    在这里插入图片描述

    参考最新官方文档发现更新之后请求的URL体发生了改变;
    旧:http://api.map.baidu.com/geocoder/v2/?location=34.35555,107.32518&output=json&ak=你的AK&pois=1
    新:http://api.map.baidu.com/reverse_geocoding/v3/?ak=你的AK&output=json&coordtype=wgs84ll&location=31.225696,121.49884

    将URL体参考文档更改之后填上自己的AK,问题完美解决;
    请参考最新官网文档: http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding-abroad

    展开全文
  • 下面是《Android Studio开发实战 从零基础到App上线(第2版)》书用到的工具和代码资源: 1、本书使用的Android Studio版本为3.2,最新的安装包可前往Android官网页面下载。 2、本书使用的Android NDK版本为r17,...

    资源下载

    下面是《Android Studio开发实战 从零基础到App上线(第2版)》一书用到的工具和代码资源:
    1、本书使用的Android Studio版本为3.2,最新的安装包可前往Android官网页面下载
    2、本书使用的Android NDK版本为r17,最新的安装包可前往Android官网页面下载
    3、本书提供所有示例源码的demo工程下载,源码(适配Android4.1到9.0和Android Studio 3.2到3.4)的下载页面为https://pan.baidu.com/s/14NE2DD-frXxuDXUAlTfRaw。最新的源码也可访问我的github获取,github地址是https://github.com/aqi00/android2,服务端的github地址是https://github.com/aqi00/net_server。(部分地区如新疆既访问不了百度网盘也访问不了github,此时可访问csdn的下载页面获取源码https://download.csdn.net/download/aqi00/11223223)。另外,AS3.4之后默认开了androidx,如需获取适配了androidx的本书源码,可访问这个github页面https://github.com/aqi00/androidx
    有的读者反映从github下载本书源码很慢,或者下载不完整,这是国外服务器连接不稳定造成的。建议访问这个代下载网站https://d.serctl.com/,按照网站左上角的“如何下载教程”,找到本书源码的github下载地址并提交,等待几秒后就能在该网站下载完整的源码了。
    源码与各章的对应关系表见下图:

    4、本书提供配套的ppt课件下载,第二版课件的下载页面为https://www.jianguoyun.com/p/DX7Y1J4QlP6kCBiUoIkD
    5、本书第8章使用了一些反编译和重签名工具,这些工具的下载页面是https://pan.baidu.com/s/1EzDMLNdTdh2pDO7NBMiiww (提取码93i5)


    参考资料

    1、学习本书需要具备Java基础,所谓“零基础”指的是安卓零基础,如果您没学过Java的话,可学习以下系列的Java教程《Java开发笔记》
    2、由于篇幅所限,本书只覆盖了较为常见的Android开发技术,其余的Android开发技术可参考以下的Android笔记《Android开发笔记》
    3、本书的技术实现采用的是Java编码,若您想进一步了解App开发中的Kotlin编程技术,可阅读以下系列的Kotlin教程《Kotlin入门教程》
    4、更多有关本书内容的常见问题参见博文《Android Studio开发实战 从零基础到App上线(第2版)》常见问题解答
    5、有关Android8、Android9、Android10的更多代码适配参见博文《Android8.0、9.0、10.0的新特性兼容适配代码修改》。
     

    勘误记录

    下面对书中的笔误之处进行更正说明:

    一、第一批勘误记录(以下的勘误记录在2019年1月的第二次印刷时均已修正):

    1、第1页“1.1  Android Studio简介”
    该小节第三段第三行“本书使用的Android Studio为2018年4月发布的3.1.2版本”,这里的“4月”改为“9月”,“3.1.2版本”改为“3.2版本”。

    2、第428页“10.2.4 HTTP接口访问”
    倒数第四行的connect方法,该行后面的“该方法在getOutputStream后调用,在getInputStream前调用。”整个删掉。因为connect方法和getOutputStream方法没有先后调用关系,getOutputStream方法内部会自动调用connect方法。

    3、第430页“1. URL串中对汉字的转义处理”
    在“具体的转义代码参见本书下载资源的URLtoUTF8.java”这句后面补充“,也可使用系统自带的java.net.URLEncoder和java.net.URLDecoder”。

    4、第451页“10.5.1 设计思路”下面的第三行
    “于是在打开系统自带的应用宝”,这句前半部分的“”字删掉。

    5、第675页“2. 蓝牙设备BluetoothDevice”
    表14-6出现了两个BOND_BONDING,要把后面的“BOND_BONDING”改为“BOND_BONDED”。

    二、第二批勘误记录(以下的勘误记录在2019年6月的第四次印刷时均已修正):

    1、第46页“2.4.1  图形Drawable”
    该页中间“开发者拿到一张图片”这段的第二行中“Android Postfix Completion”要改为“Android Drawable Importer”。

    2、第447页的“10.4.2  Socket通信”
    在“1. Socket”该段下面的方法说明中,“getOutputStream:获取输入流”,这里的“输入流”要改为“输出流”。

    3、第650页“14.1.2  网页视图WebView”
    该页代码的倒数第七行,把“http://”改为“https://”,也就是添加字母s

    4、第654页“14.1.3  简单浏览器”
    该页代码的倒数第八行,把“http://”改为“https://”,也就是添加字母s

    三、第三批勘误记录(以下的勘误记录在2019年11月的第六次印刷时均已修正):

    1、第94页的图3-31,最后一行“2012年07月06日 五年期商贷利率”的数值改为 “6.55%”,原来的6.15%跟2014年的商贷利率重复了。

    2、第271页的“7.4.1  循环视图RecyclerView”
    该小节第二段第一行的“为了兼容以前的Adnroid版本”,这里的Adnroid拼错了,要改为Android

    3、第409页的“10.1.1  消息传递Message”
    第6行的注释“// 从布局文件中获取名叫tv_control的文本视图”,这里的“tv_control”改为“tv_message

    4、第410页的“10.1.1  消息传递Message”
    代码倒数第10行的“下面播放新闻”,这里的“下面”改为“开始”。

    四、第四批勘误记录(以下的勘误记录在2020年4月的第八次印刷时均已修正):

    1、第225页的“6.5.1  Service的生命周期”
        该节第一段第三行在“App也可以有自己的服务。”后面补充以下红字部分:
    App也可以有自己的服务。此时需要在AndroidManifest.xml中添加新服务的Service节点配置,比如:
            <service android:name=".service.NormalService" />

    2、第353页的表9-6
        该表最后两行的说明都是“高效率的高级编码”,需要把最后一行AAC_ELD的说明改为“增强型低延时的高级编码”。
    3、第430页的“10.2.4  HTTP接口调用”
        该页中间在“下面用一个阶段性的实战小项目练练手”这句前面补充以下红字部分:
    除此之外,从Android9开始默认只能访问以https打头的安全地址,不能直接访问http打头的网络地址。如果应用仍想访问以http开头的普通地址,就得修改AndroidManifest.xml,给application节点添加如下属性,表示继续使用HTTP明文地址:
            android:usesCleartextTraffic="true"

    下面用一个阶段性的实战小项目练练手

    五、第五批勘误记录(以下的勘误记录在2020年9月的第九次印刷时均已修正):

    1、第21页的“1.5.5  新建一个Activity页面”
    该页第一段在“在res\layout下面生成页面布局activity_main2.xml”后面补充以下红字部分:
    在res\layout下面生成页面布局activity_main2.xml,还会在AndroidManifest.xml的application节点增加下面一行配置:
            <activity android:name=".Main2Activity"></activity>

    新页面创建之后的工程结构如图1-37所示。

    2、第52页的“2.4.4  九宫格图片”
    图2-26下面说明文字的第二行,“未拉伸预览”改为“两方向同时拉伸预览

    3、第66页的“3.2.2  开关按钮Switch”
    表3-2,倒数第二行thumb的说明列改为“设置开关标识的图标”,倒数第一行track的说明列改为“设置开关轨道的背景”,也就是倒数两行的说明文字互换

    4、第72页的“3.4.1  文本编辑框EditText”
    表3-3,第三行textPassword和第七行numberPassword两行右边的说明列,“星号“*””改为“圆点“•”

    5、第83页的“3.5.2  使用Intent传递消息”
    表3-5的第六行第三列的“数据类型,用于指定Data类型的定义”,这里的表达比较拗口不易理解,要把“Data类型的定义”改为“消息的数据类型

    6、第88页的“3.5.4  向上一个Activity返回参数”
    第一段第三行的“如果还要处理一下个页面的应答数据”,这里的“一下个页面”改为“下一个页面

    7、第171页的“5.4.2  动态注册/碎片适配器FragmentStatePagerAdapter”
    该页第一行“然后在Fragment的onCreateView函数中调用getArguments方获得请求数据”,这里的“getArguments方”改为“getArguments方法”,也就是添加“法”字。

    8、第214页的“6.4.1  通知推送Notification”
    参数构建方法的第三个方法setUsesChronometer,把“设置是否显示计数器”里面的“计数器”改为“计时器”。

    9、第237页的“7.1.1  标签按钮”
    该页第二行的“读者还记得第2章”,这里的“第2章”改为“第3章

    10、第663页的“14.2.2  创建JNI接口”
    “具体的编译配置修改说明如下”这句后面的代码有若干处需要修改,修改之处见下面的红字:
    android {
        compileSdkVersion 28
        buildToolsVersion "28.0.3"

        defaultConfig {
            applicationId "com.example.mixture"
            minSdkVersion 16
            targetSdkVersion 28
            versionCode 1
            versionName "1.0"

            // 此处说明mk文件未能指定的编译参数
            externalNativeBuild {
                ndkBuild {
                    // 说明需要生成哪些处理器的so文件
                    // NDK的r17版本开始不再支持ARM5(armeabi)、MIPS、MIPS64这几种类型
                    abiFilters "arm64-v8a", "armeabi-v7a"
                    // 指定C++编译器的版本,比如下面这行用的是C++11
                    //cppFlags "-std=c++11"
                }
            }
        }

        // 下面指定拾取的第一个so库路径,编译时才不会重复链接
        packagingOptions {
            pickFirst 'lib/arm64-v8a/libjni_mix.so'
            pickFirst 'lib/armeabi-v7a/libjni_mix.so'
            pickFirst 'lib/arm64-v8a/libvudroid.so'
            pickFirst 'lib/armeabi-v7a/libvudroid.so'
        }

        // Android Studio 2.2之后才引入externalNativeBuild。此处指定mk文件的路径
        externalNativeBuild {
            ndkBuild {
                // 下面是编译CPU信息、加解密、获取主机名专用的mk文件
                path "src/main/jni/Android.mk"
                //path file("src\\main\\jni\\Android.mk")
            }
        }
    }

    六、第六批勘误记录(以下的勘误记录在2021年2月的第十次印刷时均已修正):

    1、第35页的“2.2.3  滚动视图ScrollView”
    该小节示例代码中的两处“线性视图”都改为“线性布局”。

    2、第97页的“3.7.2  小知识:提醒对话框AlertDialog”
    该小节示例代码第七行的“给建造器设置对话框的信息文本”,把“信息文本”改为“内容文本”。

    3、第195页的““6.1.1  声明属性””
    表6-1删掉第七行整行(getDimension那行),同时第八行(getDimensionPixelSize那行)的说明列文字改为“尺寸值。单位为px”。

    4、第204页的“6.1.5  绘制视图”
    在“2. onDraw”的“(1)划定可绘制的区域”下的第一句“虽然本视图内的所有区域都是可以绘制的”,改为“虽然视图内的所有区域都是可以绘制的”,也就是去掉“本”字

    5、第233页的“6.5.1  Service的生命周期”
    “3. 延迟绑定”小节的第二行,把“因为启动操作在先”改为“因为启动操作在先、绑定操作在后”,也就是补充“、绑定操作在后”这几个字。

    6、第335页的“9.2.3  录音与播音”
    “1. 媒体录制器MediaRecorder”小节的常用方法列表中,第一行reset后面的文字说明“重置录制资源”改为“重置录制器”,第五行release后面的的文字说明“释放录制资源”改为“释放录制器”。

    七、第七批勘误记录:

    1、第55页“2.5.2  小知识:日志Log/提示Toast”开始
    “2.5.2  小知识:日志Log/提示Toast”和“2.5.3  代码示例”这两个小节共有七处“被除数”要改为“除数”,因为除法运算要检查除数是否为零,而不是检查被除数是否为零。

    2、第114页的“4.3.1  SD卡的基本操作”
    第三行“<uses-permission android:name="android.permission.READ_EXTERNAL_STORAG" />”改为“<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />”,也就是在STORAG末尾加个E变成STORAGE

    3、第136页的“4.6.3  代码示例”
    该页中间“声明SD卡的操作权限”下面第三行“<uses-permission android:name="android.permission.READ_EXTERNAL_STORAG" />”改为“<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />”,也就是在STORAG末尾加个E变成STORAGE

    4、第232页的“6.6.2  小知识:应用包管理器PackageManager”
    该小节开始的代码例子第9行的“PackageManager.PERMISSION_GRANTED”改为“PackageManager.MATCH_UNINSTALLED_PACKAGES”。

    5、第336页的“9.1.1  表面视图SurfaceView” 
    该页第二行的“这个途径便是内部类表面持有者SurfaceHolder外部调用”改为“这个途径便是内部类表面持有者SurfaceHolder外部调用”,也就是在“外部调用”前面增加一个句号。

    6、第338页的“9.1.2  使用Camera拍照” 
    autoFocus方法的说明文字“参数自动对焦接口AutoFocusCallback的onAutoFocus方法在对焦完成时触发”语句不通顺,改为“输入参数为自动对焦接口AutoFocusCallback的实例,该接口的onAutoFocus方法在对焦完成时触发”。

    7、第345页的“9.1.4  使用Camera 2拍照”
    该页最后一行,“4. 图像读取器ImageReader”小节中,getSurface的方法说明文字“获得图像读取的表面对象”改为“获得图像读取的表面对象”,也就是增加一个“”字。

    8、第349页的“9.2.1  拖动条SeekBar”
    该小节第一行“拖动条SeekBar继承自进度条ProcessBar”,把“ProcessBar”改为“ProgressBar”。

    9、第353页的“9.2.3  录音与播音” 
    setAudioSamplingRate方法后面的描述文字“单位千赫兹(kHz)”改为“单位赫兹(Hz)”。

    10、第364页的“9.3.2  摇一摇——加速度传感器”
    该小节第二行末尾的“其他类似的应用还摇骰子”改为“其他类似的应用还摇骰子”,也就是增加一个“”字。

    11、第381页的“9.5.1  NFC近场通信” 
    “2. 启用NFC感应/禁用NFC感应”小节第一段第一行和第三行的两处“重载”改为“重写”。

    12、第516页的“11.6.2  小知识:三维图形接口OpenGL” 
    该小节第三段第四行的“比如显示生活中黑板的漆面”改为“比如现实生活中黑板的漆面”,也就是把“显示”改为“现实”。

    13、第520页的“11.6.2  小知识:三维图形接口OpenGL” 
    “此时自定义的渲染器GLRender必须重载onSurfaceCreated”这句里面的“重载”改为“重写”。

    14、第553页的“12.3.1  属性动画的用法” 
    removeListener的方法说明改为“移除指定的动画监听器”,也就是把“移出”改为“移除”。
    removeAllListeners的方法说明改为“移除所有动画监听器”,也就是把“移出”改为“移除”。

    15、第557页的“12.3.3  插值器和估值器” 
    该小节第二段第一行的“默认是匀速播放”改为“默认是先加速再减速”。

    16、第662页的“14.2.2  创建JNI接口”
    表14-2  基本数据类型的转换关系,“Java的数据类型”该列的Int和Float要改为小写的intfloat

    17、第725页的“15.4.1  文字转语音TextToSpeech”
    图例“15-39  小米手机内置的语音引擎”改为“15-39  小米手机内置的语音引擎”,也就是在“15-39”前面加个“”。

    8、第725页的“15.4.1  文字转语音TextToSpeech”
    表15-5  setLanguage方法的返回值说明,下面表格左侧的标题由“TextToSpeech类的返回值”改为“setLanguage方法的返回值”。

    19、第726页的“15.4.1  文字转语音TextToSpeech”
    图15-41下方的文字“接下来就可以大胆设置朗读的语音了”改为“接下来就可以大胆设置朗读的语言了”,也就是把“语音”改为“语言”。
     

    若对本书内容有任何疑问,可加入QQ群进行咨询,群号是493199768

    展开全文
  • 下面分享弹窗页面, 可在用户付款备注个人会员账号开通, 特点:简单,方便,使用,更装逼。 <!--文章内容结束-->
  • 百度地图API报 APP服务被禁用

    千次阅读 2020-06-17 11:53:03
    参考最新官方文档发现更新之后请求的URL体发生了改变; 旧:...output=json&ak=你的AK&pois=1 ...output=json&coordtype=wgs84ll&location=31.225696,121
  • 在用到组件时,有时候我们可能暂时性的不使用组件,但又不想把组件kill掉,比如创建了一个broadcastReceiver广播监听器,用来想监听第一次开机启动后获得系统的许多相关信息,并保存在文件中,这样以后每次...
  • 安卓获取app禁用的组件

    千次阅读 2019-04-18 12:31:03
    app里有禁用其他第三方app组件的需求,但发现组件被禁用以后,用常用的方法无法获取被禁用的组件,代码如下: PackageManager packagemanager =this.getPackageManager(); // 获得PackageManager对象 PackageInfo ...
  • app需要进入淘宝优惠卷界面(H5)领卷购买商品,但这H5界面会自动唤起手机淘宝经检查scheme为tbopen://,我想问下怎样禁止唤起手淘?
  • 从系统层禁用app

    千次阅读 2017-10-26 16:17:52
    方法是设置里面禁用app用的方法,禁用后,在launcher界面是不显示app图标的,我们的需求是从系统层禁用app,launcher也要显示app图标,点击后提示“此应用被禁用”。好了,思路是从activity启动
  • 具体页面为 公司项目所以去除了logo与对应内容 ...顺带一提关于弹窗效果我在这里存放的是一个uniapp插件市场下载的弹出框组件(popup 弹出层组件),主键的调用方法与之前的方法一致
  • 已将该虚拟机配置为使用 64 位客户机操作系统。但是,无法执行 64 位操作。 此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态。 如果已在 BIOS/固件设置中禁用
  • 在微信小程序开发中使用百度地图API,在申请微信小程序所对应的AK后,发现调用API报错"APP 服务被禁用...在一番查找之后,需要创建一个server类型的AK,这样小程序调用百度地图的API进行周边检索等操作就正常了。 ...
  • uni-app禁用原生导航

    千次阅读 2019-02-13 14:07:36
    最近在使用uni-app开发毕设,遇到一个需求是去掉原生导航,可是去掉后,发现整个页面直接顶到手机通知栏里面去了,处理如下: 去掉原生导航:(pages.json) "globalStyle" : { "...
  • 使用APP inventor来制作一个属于自己的蓝牙串口软件

    千次阅读 多人点赞 2021-03-05 11:33:33
    使用APP inventor来制作一个属于自己的蓝牙串口软件 本文主要讲述蓝牙的发送和接收功能的制作 一、准备 1.APPinventor的网址:http://app.gzjkw.net/ 二、蓝牙APP界面的设置 首先我们新建一个项目,在这里我用的是...
  • android app 禁用statusbar 功能

    千次阅读 2017-08-23 11:30:15
    最近被要求研究下怎么在app层面禁止android的statusbar功能,查阅了资料以及系统的statusbar源码,发现真正的禁用statusbar的功能,基本都是系统应用调用statusBarManager 的disable方法,但是要调用到这方法需要...
  • 一键禁用系统APP 这次介绍的 禁用系统APP 方法 是通过 ADB命令行 来实现的 无需额外安装任何其他第三方APP APP禁用后,也可以通过命令行随时恢复 准备工作 .手机激活USB调试 方法请点击我前往 准备工作...
  • 在 macOS 上禁止 App 连网的一个方法

    千次阅读 2019-12-15 18:30:10
    在 macOS 上禁止 App 连网的一个方法 在 macOS 上可以使用沙盒策略来禁止 App 连网。 App 假设目标 App 的目录结构如下: /Applications/AbcdEfg.app └── Contents ├── Info.plist ├── MacOS │ ...
  • Android在App中强制关闭禁用深色模式

    千次阅读 2021-01-20 17:37:22
    1.主要是以下这属性 <item name="android:forceDarkAllowed" tools:targetApi="q">false</item> 2.完整的代码 <?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools=...
  • app.json: "permission": { "scope.userLocation": { "desc": "需要获取您的地理位置,请确认授权" } }, js: getUserLocation: function () { wx.getSetting({ success: (res) => { ...
  • 仅在iOS上 打开manifest源码视图,app-plus下配 "popGesture": "none" iOS上是否支持屏幕左边滑动关闭当前页面。设为none则不响应左滑动画。
  • 关于APP清理缓存

    2016-10-15 13:37:39
    关于APP清理缓存
  • * check the app is installed */ public static boolean isAppInstalled(String packageName) { PackageInfo packageInfo; ApplicationInfo applicationInfo = null; try { packageInfo...
  • 1.在pages.json中配置 比如要首页禁用 就在首页这选项里 加上这几句代码 2.效果如下 转载于:https://www.cnblogs.com/wordblog/p/10606432.html
  • 一个简单的应用 给app授予root权限并执行shell命令 急需又没资源的可以直接联系我 我会尽快回复你 或者qq邮箱
  • 种简单快速的方式实现 Android App 的夜间模式

    万次阅读 多人点赞 2019-07-02 01:08:57
    博主声明: 转载请在开头附加本文...在现在的很多应用中,都有一个夜间模式,由于大部分人玩手机都到深更半夜,白色的主题在夜晚不开灯的情况下,显得屏幕非常亮。一种办法是降低屏幕的亮度,就比如我的手机一般...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 86,753
精华内容 34,701
关键字:

如何禁用一个app