飞飞的AI实验室

用AI放大灵感,把想法变成作品。

Android studio 3.0 版本出来也好长时间了,自己的电脑每次有更新我就立马回更新成最新的,公司的电脑自从装上AS就没有更新过,主要是工作比较忙没有时间去更新,这不周末把电脑带回来想着更新成最新的版本…

##1.开始更新

打开AS 点击Help –> Check for Updates…

等了一小会后弹出的是Download而不是Update and Restart安装更新并重启的按钮,点击Download按钮之后,跳转到浏览器,让下载新版本,纳尼?这是什么鬼?我自己的电脑每次更新都是自己下载安装完补丁之后自动安装并重启的,下载完再安装也是可以的,就是比较麻烦而已,而我不想使用这种方式去安装,最后搜了一下大概的意思就是Android Studio的版本太低了不支持使用更新补丁的方式升级到最新的版本,我现在的版本是2.2.3想升级到最新的3.0.1版本,而Google不提供补丁包,可能是版本跨度太大了吧,我想着肯定是有办法的,最后在CSDN上找到一篇博客,和我的情况一样,使用手动更新Android Studio到最新版本,按照他的办法步骤如下:

###1.1找到最新的版本号对应的串号

https://dl.google.com/Android/studio/patches/updates.xml

如下图所示:

###1.2下载你对应版本的到最新版本的补丁包

点开AS的Setting->在点开Update就可以看到当前版本的串号,如下图:

然后拼接出一个下载补丁包的url:如下

阅读全文 »

每次升级Android Studio时,一般情况下 Gradle 版本的也会相应的升级,我之前Android Studio 3.0.1、Gradle 是 4.1 升级后为:Android Studio 3.1.0、Gradle 为4.4。

升级完成后先是报一堆错(每次都升级都是-。-)

##第一个错如下:

1
The SourceSet 'instrumentTest' is not recognized by the Android Gradle Plugin. Perhaps you misspelled something?

翻译过来就是:

1
“SourceSet” 的'instrumentTest' 没有被Android Gradle插件识别。也许你拼错吗?

猜想可能Gradle移除了’instrumentTest’关键字,网上搜了一下,博客地址如下:http://www.it1352.com/139247.html

新版本Gradle对其做了重命名

即:

 旧版本 - > 新版本

 instrumentTestCompile - > androidTestCompile 

 instrumentTest  - > androidTest 
阅读全文 »

##1.将arr库放到libs下面

##2.在app的buildgradle的android节点中添加如下代码

{
1
2
3
4
    flatDir {
dirs 'libs' //this way we can find the .aar file in libs folder
}
}

##3.在dependencies中添加如下依赖

compile(name: 'com.datescroller.lib-release', ext: 'aar')

name后面就是arr的库名,不带后缀。

阅读全文 »

Android Studio 新增了依赖library的方式,有时候我们需要将一个 library 打成 jar 包供其他人使用下面就是具体打成的方法:

##1.在library的buildgradle中添加如下代码

1
2
3
4
5
6
7
task makeJar(type: Copy) {
delete 'build/libs/myjar.jar'
from('build/intermediates/bundles/release/')
into('build/libs/')
include('classes.jar')
rename('classes.jar', 'myjar.jar')
}

其实,当你编译完整个工程后,所有library库都已经生成了对应的包含class的classes.jar包,复制出这个jar包,修改名字后也可以使用了,默认生成的路径为:build/intermediates/bundles/release下面就可以看到生成的classes.jar文件了。

##2.如果你不想使用如上编译时生成的Jar包,你可以再Android Studio自带的Terminal中输入如下命令生成jar包
在终端执行生成JAR包
./gradlew build

或者在buildgradle中再添加如下两行代码即可

1
2
makeJar.dependsOn(build)   
//build.finalizedBy makeJar

Android Studio新增了@arr的依赖方式,它的好处是可以将资源文件也可以打进去,所以,我更推荐大家使用这种依赖方式。

最后他特别感谢如下博主的文章:

参考:blog:http://blog.csdn.net/ta893115871/article/details/46955791

阅读全文 »

##一、使用TextView属性来实现

1.布局文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<TextView
android:id="@+id/tvNotice"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ico_tongzhi"
android:drawablePadding="12dp"
android:ellipsize="marquee"
android:gravity="center_vertical"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="@string/notice_content"
android:textColor="@color/white"
android:textSize="24sp"
android:visibility="visible" />

2.代码中

1
2
3
4
tvContent.setText("xxxx...");
tvContent.setFocusable(true); // 获取焦点
tvContent.setFocusableInTouchMode(true);
tvContent.requestFocus();

##二、使用自定义View实现

1.继承TextView并重写isFocused方法,返回true,让其获取焦点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Created by xpf on 2016/11/19 :)
* Function:自定义Marquee textView
*/

public class MyTextView extends TextView {

public MyTextView(Context context) {
super(context);
}

public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
public boolean isFocused() {
return true;
}
}

2.布局文件中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<com.anloq.ui.MyTextView
android:id="@+id/tvNotice"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ico_tongzhi"
android:drawablePadding="12dp"
android:ellipsize="marquee"
android:gravity="center_vertical"
android:scrollHorizontally=“true”
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="@string/notice_content"
android:textColor="@color/white"
android:textSize="24sp"
android:visibility="visible" />
阅读全文 »

现在许多应用都有上传头像的功能,再次奉上代开系统相册或打开系统相机拍照的实现,有的同学在测试小米手机上打开选择相册有奔溃,此代码已完美解决此问题…

楼主,做的头像需要经过裁剪之后和圆形处理…

1.设置点击打开相机&打开系统图库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public void onClick(View v) {
// 打开系统拍照程
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(camera, CAMERA);
}


@Override
public void onClick(View v) {
// 打开系统图库选择图片
Intent picture = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(picture, PICTURE);
}

2.重写带结果启动的回调onActivityResult

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == CAMERA && resultCode == RESULT_OK && data != null) {

// 拍照
Bundle bundle = data.getExtras();
// 获取相机返回的数据,并转换为图片格式
Bitmap bitmap = (Bitmap) bundle.get("data");
// bitmap圆形裁剪
// bitmap = BitmapUtils.zoom(bitmap, DensityUtil.dp2px(this, 62), DensityUtil.dp2px(this, 62));
bitmap = BitmapUtils.zoom(bitmap, DensityUtil.dp2px(this, 20), DensityUtil.dp2px(this, 20));
Bitmap circleBitmap = BitmapUtils.circleBitmap(bitmap);

//TODO 将图片上传到服务器
// ivIcon.setImageBitmap(circleBitmap);
uploadHeadpic(bitmap);
// 将图片保存在本地
try {
saveImage(circleBitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else if (requestCode == PICTURE && resultCode == RESULT_OK && data != null) {
//图库

String pathResult = null; // 获取图片路径的方法调用
try {
Uri uri = data.getData();
pathResult = getPath(uri);
Log.e("TAG", "图片路径===" + pathResult);
} catch (Exception e) {
e.printStackTrace();
}

//这里返回的uri情况就有点多了
//**:在4.4.2之前返回的uri是:content://media/external/images/media/3951或者file://....在4.4.2返回的是content://com.android.providers.media.documents/document/image:3951或者
//总结:uri的组成,eg:content://com.example.project:200/folder/subfolder/etc
//content:--->"scheme"
//com.example.project:200-->"host":"port"--->"authority"[主机地址+端口(省略) =authority]
//folder/subfolder/etc-->"path" 路径部分
//android各个不同的系统版本,对于获取外部存储上的资源,返回的Uri对象都可能各不一样,所以要保证无论是哪个系统版本都能正确获取到图片资源的话
//就需要针对各种情况进行一个处理了

Bitmap decodeFile = BitmapFactory.decodeFile(pathResult);
Bitmap zoomBitmap = BitmapUtils.zoom(decodeFile, DensityUtil.dp2px(this, 20), DensityUtil.dp2px(this, 20));
// bitmap圆形裁剪p
Bitmap circleImage = BitmapUtils.circleBitmap(zoomBitmap);
// 真实项目当中,是需要上传到服务器的..这步我们就不做了。
uploadHeadpic(zoomBitmap);
try {
// 保存图片到本地
saveImage(circleImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}

3.获取图片路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// 根据系统相册选择的文件获取路径
@SuppressLint("NewApi")
private String getPath(Uri uri) {
// int sdkVersion = Build.VERSION.SDK_INT;
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// 高于4.4.2的版本
// if (sdkVersion >= 19) {
if (isKitKat && DocumentsContract.isDocumentUri(mContext, uri)) {
Log.e("TAG", "uri auth: " + uri.getAuthority());
if (isExternalStorageDocument(uri)) {
String docId = DocumentsContract.getDocumentId(uri);
String[] split = docId.split(":");
String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(this, contentUri, null, null);
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];

Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(this, contentUri, selection, selectionArgs);
} else if (isMedia(uri)) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor actualimagecursor = this.managedQuery(uri, proj, null, null, null);
int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
actualimagecursor.moveToFirst();
return actualimagecursor.getString(actual_image_column_index);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(this, uri, null, null);

} else if ("file".equalsIgnoreCase(uri.getScheme())) { // File
return uri.getPath();
}
return null;
}

private String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}


private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}

public static boolean isMedia(Uri uri) {
return "media".equals(uri.getAuthority());
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}

以上就是比较完整的代码了…

最后附上2篇参考文章:

阅读全文 »

需求:现在在做一个app要求有唤醒屏幕并解锁的需求,参考了网上的许多的博客,感觉前篇一律,有的手机上好使,在有的手机上不好使,参考了微信的视频呼叫唤醒屏幕,可以点亮手机屏幕,对于有上滑手势解锁的手机只能点亮屏幕不能解锁屏幕,后来经过尝试,当前应用中有一个锁屏弹起界面 的权限,默认是关闭的,打开这个权限之后就可以点亮屏幕并弹出界面了(有上滑手势解锁的手机),后台经过尝试现在可以点亮屏幕并解锁了…

##代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 唤醒手机屏幕并解锁
*/
public static void wakeUpAndUnlock() {
// 获取电源管理器对象
PowerManager pm = (PowerManager) MyApplication.getContext()
.getSystemService(Context.POWER_SERVICE);
boolean screenOn = pm.isScreenOn();
if (!screenOn) {
// 获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是LogCat里用的Tag
PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
wl.acquire(10000); // 点亮屏幕
wl.release(); // 释放
}
// 屏幕解锁
KeyguardManager keyguardManager = (KeyguardManager) MyApplication.getContext()
.getSystemService(KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("unLock");
// 屏幕锁定
keyguardLock.reenableKeyguard();
keyguardLock.disableKeyguard(); // 解锁
}

注意:好多写法都是wl.acquire() 这样写的,在有的手机上不好使,后来我这样写wl.acquire(10000); // 点亮屏幕然后就好使了,我的理解是这样的:是不是时间太短了,刚唤醒屏幕就释放掉了会有问题,由于水平有限不对的地方请指出。

测试机型:xiaomi 5, OPPO R9s plus.

其他机型请自测。

##不要忘了添加如下权限

1
2
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />

Thanks.

参考文章:http://blog.csdn.net/glen1943/article/details/8671793

阅读全文 »

##方式一

1
2
3
4
5
public static Bitmap capture(Activity activity) {
activity.getWindow().getDecorView().setDrawingCacheEnabled(true);
Bitmap bmp = activity.getWindow().getDecorView().getDrawingCache();
return bmp;
}

此种方式比较简单只需传入当前要截取屏幕的Activity对象即可,不需要添加任何权限,后续可将截图的bitmap保存到本地即可;

缺点:无法截取WebView页面,截屏后是白屏!

##方式二

使用adb Shell命令截屏

例如:

adb shell screencap -p /sdcard/sreenshot1.png

命令格式:adb shell screencap -p + 文件路径 + 文件名

##方式三

阅读全文 »

##1.第一种:隐藏页面一进来EditText获取焦点就弹出软键盘

在**oncreate()**里调用如下方法即可

1
2
3
4
5
6
7
/**
* 隐藏软键盘
*/
private void hideSoftKeyBoard() {
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}

##2.第二种:如果EditText获取焦点已经弹起软键盘,点击其他空白区域隐藏软键盘

此方法可以写到BaseActivity中其他Activity就相应的也会继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (isShouldHideKeyboard(v, ev)) {
hideKeyboard(v.getWindowToken());
}
}
return super.dispatchTouchEvent(ev);
}

/**
* 根据EditText所在坐标和用户点击的坐标相对比,
* 来判断是否隐藏键盘,因为当用户点击EditText时则不能隐藏
*/
private boolean isShouldHideKeyboard(View v, MotionEvent event) {
if (v != null && (v instanceof EditText)) {
int[] l = {0, 0};
v.getLocationInWindow(l);
int left = l[0],
top = l[1],
bottom = top + v.getHeight(),
right = left + v.getWidth();
if (event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom) {
// 点击EditText的事件,忽略它。
return false;
} else {
return true;
}
}
// 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上,和用户用轨迹球选择其他的焦点
return false;
}

/**
* 获取InputMethodManager,隐藏软键盘
*/
private void hideKeyboard(IBinder token) {
if (token != null) {
InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
}
}

Thanks all.

2017.6.21 beijing 雨

阅读全文 »

1
2
3
4
5
6
7
8
9
10
11
// 向右边移出
llVideo.setAnimation(AnimationUtils.makeOutAnimation(this, true));
// 向右边移入
llVideo.setAnimation(AnimationUtils.makeInAnimation(this, true));

llVideo.setVisibility(View.VISIBLE);
llVideo.setVisibility(View.GONE);
// 向左边移入
llVideo.setAnimation(AnimationUtils.makeInAnimation(this, false));
// 向左边移出
llVideo.setAnimation(AnimationUtils.makeOutAnimation(this, false));
阅读全文 »
0%