USB调试不能弹出授权窗口 unauthorized 的解决办法

在首次使用adb connect,然后adb shell的时候,常常需要点击弹出的对话框,否则出现

error: device unauthorized. Please check the confirmation dialog on your device.
这种情况在没有显示屏的时候或者多人连接时不太方便。这时候想默认授权而不用点击对话框想要去除弹框。
先了解它的工作原理,以下来自
-------------------------------------以下为转载--------------------------------------------------------------------------------------------
http://blog.csdn.net/sowhat_ah/article/details/43307907

工作原理是什么?

原来在我们的PC机(以windows为例)上启动了adb.exe进程时,adb会在本地生成一对密钥adbkey(私钥)与adbkey.pub(公钥);

根据弹框提示“The computer's RSA key fingerprint is:xxxx”,可以看出是一对RSA算法的密钥,其中公钥是用来发送给手机的;

当你执行“adb shell”时,adb.exe会将当前PC的公钥(或者公钥的hash值)(fingerprint)发送给android设备;这时,如果android上已经保存了这台PC的公钥,则匹配出对应的公钥进行认证,建立adb连接;如果android上没有保存这台PC的公钥,则会弹出提示框,让你确认是否允许这台机器进行adb连接,当你点击了允许授权之后,android就会保存了这台PC的adbkey.pub(公钥);

当然手机厂商也有可能会内置一些adbkey.pub(公钥);

那么问题来了,这些密钥在PC与Android上分别存储在哪里?

首先PC上,以Windows7为例,当你首次启动adb.exe时,会在C盘的当前用户的目录下生成一个".android"目录,其中adbkey与adbkey.pub就在这个目录下;(adb.exe会在启动时读取这两个文件(没有就重新生成),所以如果你要是删除或者修改了这两个文件之后,必须要关闭adb.exe进程,重启之后才能生效;)

其次Android上,PC的公钥被保存在一个文件中"/data/misc/adb/adb_keys";

在知道了adb这种认证的原理之后,你可以在不希望自己android设备授权任何PC设备进行adb链接时,清除"/data/misc/adb/adb_keys"文件;

也可以在没有屏幕的情况下,让已经认证过的PC将你PC上的adbkey.pub中的公钥导入到android中的"/data/misc/adb/adb_keys"文件中,或者将已经认证过的PC机上的adbkey与adbkey.pub拷贝到本机上覆盖你自己的adbkey与adbkey.pub,然后重启adb.exe,即可执行adb命令;

-------------------------------------------------------以上为转载---------------------------------------------------------------------------------------------------------------

因此,方法一、 根据转载的文章。在机器上建立/data/misc/adb/adb_keys 以及 在PC上建立adbkey.pub。

方法二、修改framework的代码,这里重点要说的方法,经过实验成功。

修改文件 UsbDebuggingActivity.java

  @Override
    public void onReceive(Context content, Intent intent) {
        String action = intent.getAction();
        if (!UsbManager.ACTION_USB_STATE.equals(action)) {
            return;
        }


        //: usb show UI
        //boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
        boolean connected  = false;   //给connect赋值,关掉UI
        if (!connected) {
            mActivity.finish();
        }
   //allowUsbDebugging
   try {
   IBinder b = ServiceManager.getService(USB_SERVICE);     
      IUsbManager service = IUsbManager.Stub.asInterface(b);
   service.allowUsbDebugging(true, mKey);
        } catch (Exception e) {
        Log.e(TAG, "Unable to notify Usb service", e);
    }
   //<<end

    }
}

一人我编程累

一人 我编程累
累得只想把觉睡
两眼 是辛酸泪
代码咋写都不对

重启是也不行
关机它也不灵
我狂敲键盘怒砸鼠标
异常也不停

这循环它有点绕
注释也很微妙
我看了半天稀里糊涂马隔壁我草

加断点 再抵坝
堆栈瞬间就爆炸
日志输出如雨下
看到异常就害怕

调试一夜没人陪
心想这锅该归谁
回想当初心后悔
不该重构这地雷

翻日志 看半天
博客看了几百篇
闪退还是没复现
低头又点一根烟

加着班我心烦乱
烂摊子我不想干
离职损失就几万
一拍桌子把工作换

离职 我不再忙
在家 我守空房
我闲得无聊掏出电脑
代码又写几行

ios9.3.5屏蔽升级提示描述文件

此描述文件用于屏蔽ios10升级提示,用safari打开地址,然后安装描述文件,然后重启即可,我在别的网站找到的,自己下载了一份,在自己的iphone5上试用有效,据说有效期可以到2019年,安装重启完最好到设置-通用-储存空间和icloud-管理存储空间里找到本地已经下载好的更新包并删除,然后不会再提示ios10的提示,检查更新也提示你的9.3.5是最新版,如果想升级10 就把那个描述文件删除【据说是这样,没验证】即可。

地址1:
http://www.litecoder.xyz/stf/ios9noOTA.mobileconfig
地址2:
https://oldcat.me/web/NOOTA9.mobileconfig

关于webview上传图片的坑

项目中遇到了需要在webview上传图片的需求,搜索了一把,找到几个可行的方法,同时也踩了个webview的坑,总结一下

我找到的是这样的方法

***首先 重写WebChromeClient 添加openFileChooser 方法

   // For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {//最终调用的都是这个
if (mUploadMessage != null) return;//坑就在这里 看后边注释
mUploadMessage = uploadMsg;
selectImage();
}

// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}

// For Android > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}



*** 然后自己实现selectImage()方法

```
private void selectImage() {//模仿IOS的弹出框
List<map <String, String>> list = new ArrayList<>();
HashMap<string , String> ch1 = new HashMap<>();
HashMap</string><string , String> ch2 = new HashMap<>();
HashMap</string><string , String> ch3 = new HashMap<>();
ch1.put("key", "从相册选择");
ch2.put("key", "拍照上传");
ch3.put("key", "取消");

<pre><code> list.add(ch1);
list.add(ch2);
list.add(ch3);
ListAdapter ad = new SimpleAdapter(this, list, R.layout.my_simple_list_item_1, new String[]{"key"}, new int[]{android.R.id.text1});
chosePicDialog = new AlertDialog.Builder(this).setAdapter(ad, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
switch (i) {
case 0:
getImageFromAlbum();

break;
case 1:
getImageFromCamera();

break;
case 2:
mUploadMessage.onReceiveValue(null);//这里是坑,如果取消了 不调用这句mUploadMessage.onReceiveValue()的话 整个webview就都没有响应了
mUploadMessage = null;//还有这里 上边已标出
break;
}

}
}).setCancelable(false).create();
chosePicDialog.getWindow().setGravity(Gravity.BOTTOM);
chosePicDialog.show();
}
</code></pre>

```

然后分别实现 从图库选择和拍照上传的方法

```
/**
* 调用相册
<em>/
protected void getImageFromAlbum() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/</em>");//相片类型
startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
}

<pre><code>/**
* 调用相机
*/
protected void getImageFromCamera() {//这里采用的是获取拍照原图的方法
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
File f = FileUtil.getNewPicFilePath();
Uri u = Uri.fromFile(f);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, u);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent,REQUEST_CODE_CAPTURE_CAMEIA);
} else {
Toast.makeText(getApplicationContext(), "请确认已经插入SD卡", Toast.LENGTH_LONG).show();
}
}
</code></pre>

```
***FileUtil.class内容

```
public class FileUtil {
private static String LastPicFilePath = null;

<pre><code>public static File getNewPicFilePath() {
String dirStr = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";

File dir = new File(dirStr);
if (!dir.exists()) {
dir.mkdirs();
}
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
String nowTime = format.format(new Date());
String localTempFileName = nowTime + ".jpg";
File f = new File(dir, localTempFileName);
setLastPicFilePath(f.getPath());
Log.e("getLastPicFilePath",getLastPicFilePath());
return f;
}

public static String getLastPicFilePath() {
return LastPicFilePath;
}

public static void setLastPicFilePath(String lastPicFilePath) {
LastPicFilePath = lastPicFilePath;
}
</code></pre>

}
```
***再重写onActivityResult

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
mUploadMessage.onReceiveValue(null);//这里防止拍照的时候取消了回来webview无响应的问题,这里是大坑
mUploadMessage = null;//上边注释说了,这里是坑
mWebView.requestFocus();
return;
}
if (requestCode == REQUEST_CODE_PICK_IMAGE) {
Uri uri = data.getData();
//to do find the path of pic by uri
mUploadMessage.onReceiveValue(uri);
} else if (requestCode == REQUEST_CODE_CAPTURE_CAMEIA) {
Uri uri = Uri.parse(FileUtil.getLastPicFilePath());//从上边指定的地址生成uri
mUploadMessage.onReceiveValue(uri);
}
super.onActivityResult(requestCode, resultCode, data);
}


总结



总体来说最坑的就是这个 mUploadMessage.onReceiveValue( );方法
没看WebChromeClient源码 猜想是如果不回调这句的话webview会一直等着你操作,造成整个webview界面没有响应,这个问题让我纠结了一下午时间,总结出来,希望对其他人有帮助。

解决 WordPress“正在执行例行维护,请一分钟后回来”

ps:今天看到wordpress有更新了,果断更新,但是不知道怎么回事,结果一直停留在“正在执行例行维护,请一分钟后回来”的状态了,这个问题一定有解决方法,所以搜索到了这篇文章,已测,可行。感谢原作者



WordPress在升级程序、主题、插件时,都会先切换到维护模式,也就是显示 “正在执行例行维护,请一分钟后回来(Briefly unavailable for scheduled maintenance. Check back in a minute)”,如果升级顺利,也就几秒左右就恢复正常;但是如果由于网速不佳等原因导致升级中断,WordPress就会一直停留在维护模式,不论前台还是后台,都一直显示“正在执行例行维护,请一分钟后回来“。

如何解决这个问题呢?

1.马上通过FTP登录你的网站,删除WordPress根目录下的 .maintenance ,刷新网页即可。

2.但是有时候你会发现,根目录根本就没有 .maintenance!倡萌最近就遇到这个问题,最初以为是隐藏了,所以使用SSH登录服务器,但是依旧没有看到,怎么办?其实有一个比较简单的办法,直接新建一个空的txt文本,上传到主机空间中,然后重命名为 .maintenance,然后你会发现 .maintenance 居然不见了!不用担心,重新刷新你的网站,是不是正常了?!

3.如果还是不行,或者你想让它以后可以显示 .maintenance ,那就打开 /wp-admin/includes/class-wp-filesystem-direct.php

找到下面的代码:


function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
// safe mode fails with a trailing slash under certain PHP versions.
$path = untrailingslashit($path);
if ( empty($path) )
return false;

if ( ! $chmod )
$chmod = FS_CHMOD_DIR;

if ( ! @mkdir($path) )
return false;
$this->chmod($path, $chmod);
if ( $chown )
$this->chown($path, $chown);
if ( $chgrp )
$this->chgrp($path, $chgrp);
return true;
}



将其改为:


function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
// safe mode fails with a trailing slash under certain PHP versions.
if ( ! $chmod )
$chmod = $this->permission;

if(ini_get('safe_mode') && substr($path, -1) == '/')
{
$path = substr($path, 0, -1);
}

if ( ! @mkdir($path) )
return false;
$this->chmod($path, $chmod);
if ( $chown )
$this->chown($path, $chown);
if ( $chgrp )
$this->chgrp($path, $chgrp);
return true;
}



然后刷新FTP目录,是不是看到.maintenance了,删除它吧!

原文链接:http://www.wpdaxue.com/briefly-unavailable-for-scheduled-maintenance.html