DeYi 技术博客

总结&记录


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

animation

发表于 2017-10-19

Animation Resources
View Animation : Tween animation

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
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@[package:]anim/interpolator_resource"
android:shareInterpolator=["true" | "false"] >
<alpha
android:fromAlpha="float" where 0.0 is transparent and 1.0 is opaque.
android:toAlpha="float" />
<scale
android:fromXScale="float"
android:toXScale="float"
android:fromYScale="float"
android:toYScale="float"
android:pivotX="float"
android:pivotY="float" />
<translate
android:fromXDelta="float"
android:toXDelta="float"
android:fromYDelta="float"
android:toYDelta="float" />
<rotate
android:fromDegrees="float"
android:toDegrees="float"
android:pivotX="float"
android:pivotY="float" />
<set>
...
</set>
</set>

fade out after fade in
动画,执行顺序,并行,串行 sequentially simultaneously

1
2
3
4
5
6
7
8
9
10
11
12
13
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator()); //add this
fadeIn.setDuration(1000);

Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator()); //and this
fadeOut.setStartOffset(1000);
fadeOut.setDuration(1000);

AnimationSet animation = new AnimationSet(false); //change to false
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
this.setAnimation(animation);

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
anim/splash_tip.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="500"
android:fromAlpha="0.0" android:toAlpha="1.0" />
<alpha
android:duration="500"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:startOffset="500" />
</set>

filterEffectTipTv 配置里设置为隐藏的

dataBinding.filterEffectTipTv.startAnimation(
AnimationUtils.loadAnimation(this, R.anim.splash_tip));

color

发表于 2017-10-19

颜色资源
Hex Opacity Values 百分比换算

java.lang.IllegalArgumentException-Surface.lockCanvas-Surface was already locked

发表于 2017-10-19 | 分类于 编程 , android , exception
1
2
3
4
5
6
7
8
Exception locking surface
java.lang.IllegalArgumentException: Surface was already locked
at android.view.Surface.lockCanvas(Surface.java:273)
at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:977)
at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:945)
at com.caiyi.youle.camera.ui.VideoProgressView.myDraw(VideoProgressView.java:232)
at com.caiyi.youle.camera.ui.VideoProgressView.run(VideoProgressView.java:119)
at java.lang.Thread.run(Thread.java:818)

VideoProgressView.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class VideoProgressView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

@Override
public void surfaceCreated(SurfaceHolder holder) {
thread = new Thread(this);
drawing = true;
thread.start();
}

@Override
public void run() {
while (drawing) {
try {
myDraw();
Thread.sleep(80); //这里40毫秒更新一次.
} catch (Exception e) {
e.printStackTrace();
}
}
}

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
private void myDraw() {
canvas = holder.lockCanvas();

progressHeight = getMeasuredHeight();

if (canvas != null) {
canvas.drawRect(0, 0, screenWidth, progressHeight, backgroundPaint);
}

countWidth = 0;

if (!timeList.isEmpty()) {
long curSegmentTime = 0;

Iterator<Integer> iterator = timeList.iterator();
while (iterator.hasNext()) {

curSegmentTime = iterator.next(); //当前这一段的时间.

float left = countWidth;
countWidth += curSegmentTime * perWidth;
if (canvas != null) {
canvas.drawRect(left, 0, countWidth, progressHeight, progressPaint);
canvas.drawRect(countWidth, 0, countWidth + breakWidth, progressHeight, breakPaint);
}
countWidth += breakWidth;
}
}

if (timeList.isEmpty() || (!timeList.isEmpty() && timeList.getLast() <= minRecordTimeMS)) {
float left = perWidth * minRecordTimeMS;
if (canvas != null) {
canvas.drawRect(left, 0, left + minTimeWidth, progressHeight, minTimePaint);
}
}
if (currentState == State.BACKSPACE) {
float left = countWidth - timeList.getLast() * perWidth; //应该减去最后一段的时间.
float right = countWidth;
if (canvas != null) {
canvas.drawRect(left, 0, right, progressHeight, rollbackPaint);
}
}
/**
* 手指按下时,绘制新进度条
*
* 绘制一个新的刻度.
*
* 当设置新的时间过来后, 这里应该是两个时间戳的相减
*/
if (currentState == State.START) {
perProgress += perWidth * (curProgressTimeMs - lastProgressTimeMs);

float right = (countWidth + perProgress) >= screenWidth ? screenWidth : (countWidth + perProgress);

if (canvas != null) {
canvas.drawRect(countWidth, 0, right, progressHeight, progressPaint);
}
}

long curSystemTime = System.currentTimeMillis();
if (drawFlashTime == 0 || curSystemTime - drawFlashTime >= 500) {
isVisible = !isVisible;
drawFlashTime = curSystemTime;
}

if (isVisible) {
if (currentState == State.START) {
if (canvas != null) {
canvas.drawRect(countWidth + perProgress, 0, countWidth + flashWidth + perProgress, progressHeight,
flashPaint);
}
} else {
if (canvas != null) {
canvas.drawRect(countWidth, 0, countWidth + flashWidth, progressHeight, flashPaint);
}
}
}

lastProgressTimeMs = curProgressTimeMs;
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}

git-cmd-pull-rebase-error

发表于 2017-10-18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
GreatWall@GreatWall-PC MINGW64 /d/work/videoshare_android.git (master)
$ git pull --rebase
remote: Counting objects: 21, done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 21 (delta 11), reused 0 (delta 0)
Unpacking objects: 100% (21/21), done.
From git.oschina.net:huangshan309/videoshare_anroid
7a5bcb8..8f12aaa master -> origin/master
First, rewinding head to replay your work on top of it...
/mingw64/libexec/git-core/git-rebase--am: line 54: /mingw64/libexec/git-core/git: Invalid argument

git encountered an error while preparing the patches to replay
these revisions:

8f12aaa608b02f16d5e07e3cc3faa1f8a23cb4d7...0406eb59af12c590b85f70ac6883e340466bbf61

As a result, git cannot rebase them.

GreatWall@GreatWall-PC MINGW64 /d/work/videoshare_android.git ((0406eb5...))
$ git status
Not currently on any branch.
nothing to commit, working tree clean

处理方法:
git checkout master
git pull –rebase

MediaStore.Video-query

发表于 2017-10-18 | 分类于 编程 , android , android sdk , android.provider , MediaStore

MediaStore.Video
static final Cursor query(ContentResolver cr, Uri uri, String[] projection)

1
2
3
4
5
6
7
8
9
10
private void fetchVideoList() {
String[] columns = {
MediaStore.Video.VideoColumns._ID,
MediaStore.Video.VideoColumns.TITLE,
MediaStore.Video.VideoColumns.ARTIST
};
Cursor list = MediaStore.Video.query(getContentResolver(),
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, columns);
Log.i(TAG, "count: " + list.getCount());
}

比较:
ContentResolver public final @Nullable Cursor query(@RequiresPermission.Read @NonNull Uri uri,
@Nullable String[] projection, @Nullable String selection,
@Nullable String[] selectionArgs, @Nullable String sortOrder)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class	MediaStore.Video.Media
class MediaStore.Video.Thumbnails
参考:http://blog.csdn.net/chenjie19891104/article/details/6338910
String[] thumbColumns = new String[]{
MediaStore.Video.Thumbnails.DATA,
MediaStore.Video.Thumbnails.VIDEO_ID
};

String[] mediaColumns = new String[]{
MediaStore.Video.Media.DATA,
MediaStore.Video.Media._ID,
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.MIME_TYPE
};
https://stackoverflow.com/questions/20517687/mediastore-video-thumbnails-getthumbnail?lq=1
MediaStore.Video.Thumbnails
public static Bitmap getThumbnail (ContentResolver cr, long origId, long groupId, int kind, BitmapFactory.Options options)
http://www.jianshu.com/p/498c9d06c193
Android读取本地照片和视频相册

异常情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#################################################################
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(no such column: _display_name (code 1): , while compiling: SELECT _id, _data FROM videothumbnails ORDER BY _display_name)
#################################################################)
#################################################################
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:181)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:421)
at android.content.ContentResolver.query(ContentResolver.java:489)
at android.content.ContentResolver.query(ContentResolver.java:433)
at android.provider.MediaStore$Video.query(MediaStore.java:1965)
at work.wangxiang.lansodemo.LansoDemoActivity.fetchVideoList(LansoDemoActivity.java:148)
at work.wangxiang.lansodemo.LansoDemoActivity.onTest(LansoDemoActivity.java:106)

Cursor list = MediaStore.Video.query(getContentResolver(),
MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, thumbColumns);

ref

Android - MediaStore.Video.query() is returning null
开源例子

activity-override

发表于 2017-10-12 | 分类于 编程 , android , android sdk , android.app.Activity

activity lifecycle
Activity Lifecycle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Activity extends ApplicationContext {
protected void onCreate(Bundle savedInstanceState);

protected void onStart();

protected void onRestart();

protected void onResume();

protected void onPause();

protected void onStop();

protected void onDestroy();
}

other override

1
2
3
4
5
6
7
8

@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
LanSongUtil.hideBottomUIMenu(this);
}
}

adb-install-error

发表于 2017-10-12 | 分类于 编程 , android , android studio , tools
1
2
3
4
5
6
Installation failed with message Failed to finalize session : INSTALL_FAILED_INVALID_APK: /data/app/vmdl718805446.tmp/11_youle_v__________ version code 7 inconsistent with 8.
It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing.

WARNING: Uninstalling will remove the application data!

Do you want to uninstall the existing application?

failure-install-failed-invalid-apk

1
I was getting this in Android Studio and all I did to fix it was go to "Build" > "Clean Project" and it just worked.

java.lang.IllegalArgumentException-MediaMetadataRetriever.setDataSource

发表于 2017-10-11 | 分类于 编程 , android , exception
1
2
3
4
5
6
7
8
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == VideoApi.REQUEST_CODE_SELECT_VIDEO && RESULT_OK == resultCode) {
Uri videoUri = data.getData();
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(videoUri.getPath());
1
2
3
4
5
6
7
8
9
10
11
12
Caused by: java.lang.IllegalArgumentException
at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:73)
at com.caiyi.youle.MainActivity.onActivityResult(MainActivity.java:433)
at android.app.Activity.dispatchActivityResult(Activity.java:6479)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3915)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3962) 
at android.app.ActivityThread.access$1500(ActivityThread.java:180) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1543) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:207) 
at android.app.ActivityThread.main(ActivityThread.java:5791) 
at java.lang.reflect.Method.invoke(Native Method)

没有申请读写权限
WRITE_EXTERNAL_STORAGE

MediaMetadataRetriever

发表于 2017-10-10 | 分类于 编程 , android , android sdk , android.media

MediaMetadataRetriever

1
2
3
4
5
/**
* Call it when one is done with the object. This method releases the memory
* allocated internally.
*/
public native void release();

常量

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
* Do not change these metadata key values without updating their
* counterparts in include/media/mediametadataretriever.h!
*/
/**
* The metadata key to retrieve the numeric string describing the
* order of the audio data source on its original recording.
*/
public static final int METADATA_KEY_CD_TRACK_NUMBER = 0;
/**
* The metadata key to retrieve the information about the album title
* of the data source.
*/
public static final int METADATA_KEY_ALBUM = 1;
/**
* The metadata key to retrieve the information about the artist of
* the data source.
*/
public static final int METADATA_KEY_ARTIST = 2;
/**
* The metadata key to retrieve the information about the author of
* the data source.
*/
public static final int METADATA_KEY_AUTHOR = 3;
/**
* The metadata key to retrieve the information about the composer of
* the data source.
*/
public static final int METADATA_KEY_COMPOSER = 4;
/**
* The metadata key to retrieve the date when the data source was created
* or modified.
*/
public static final int METADATA_KEY_DATE = 5;
/**
* The metadata key to retrieve the content type or genre of the data
* source.
*/
public static final int METADATA_KEY_GENRE = 6;
/**
* The metadata key to retrieve the data source title.
*/
public static final int METADATA_KEY_TITLE = 7;
/**
* The metadata key to retrieve the year when the data source was created
* or modified.
*/
public static final int METADATA_KEY_YEAR = 8;
/**
* The metadata key to retrieve the playback duration of the data source.
*/
public static final int METADATA_KEY_DURATION = 9; 返回的值是 毫秒
/**
* The metadata key to retrieve the number of tracks, such as audio, video,
* text, in the data source, such as a mp4 or 3gpp file.
*/
public static final int METADATA_KEY_NUM_TRACKS = 10;
/**
* The metadata key to retrieve the information of the writer (such as
* lyricist) of the data source.
*/
public static final int METADATA_KEY_WRITER = 11;
/**
* The metadata key to retrieve the mime type of the data source. Some
* example mime types include: "video/mp4", "audio/mp4", "audio/amr-wb",
* etc.
*/
public static final int METADATA_KEY_MIMETYPE = 12;
/**
* The metadata key to retrieve the information about the performers or
* artist associated with the data source.
*/
public static final int METADATA_KEY_ALBUMARTIST = 13;
/**
* The metadata key to retrieve the numberic string that describes which
* part of a set the audio data source comes from.
*/
public static final int METADATA_KEY_DISC_NUMBER = 14;
/**
* The metadata key to retrieve the music album compilation status.
*/
public static final int METADATA_KEY_COMPILATION = 15;
/**
* If this key exists the media contains audio content.
*/
public static final int METADATA_KEY_HAS_AUDIO = 16;
/**
* If this key exists the media contains video content.
*/
public static final int METADATA_KEY_HAS_VIDEO = 17;
/**
* If the media contains video, this key retrieves its width.
*/
public static final int METADATA_KEY_VIDEO_WIDTH = 18;
/**
* If the media contains video, this key retrieves its height.
*/
public static final int METADATA_KEY_VIDEO_HEIGHT = 19;
/**
* This key retrieves the average bitrate (in bits/sec), if available.
*/
public static final int METADATA_KEY_BITRATE = 20;
/**
* This key retrieves the language code of text tracks, if available.
* If multiple text tracks present, the return value will look like:
* "eng:chi"
* @hide
*/
public static final int METADATA_KEY_TIMED_TEXT_LANGUAGES = 21;
/**
* If this key exists the media is drm-protected.
* @hide
*/
public static final int METADATA_KEY_IS_DRM = 22;
/**
* This key retrieves the location information, if available.
* The location should be specified according to ISO-6709 standard, under
* a mp4/3gp box "@xyz". Location with longitude of -90 degrees and latitude
* of 180 degrees will be retrieved as "-90.0000+180.0000", for instance.
*/
public static final int METADATA_KEY_LOCATION = 23;
/**
* This key retrieves the video rotation angle in degrees, if available.
* The video rotation angle may be 0, 90, 180, or 270 degrees.
*/
public static final int METADATA_KEY_VIDEO_ROTATION = 24;
/**
* This key retrieves the original capture framerate, if it's
* available. The capture framerate will be a floating point
* number.
*/
public static final int METADATA_KEY_CAPTURE_FRAMERATE = 25;
// Add more here...

1
String duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);

ACTION_PICK

发表于 2017-10-09 | 分类于 编程 , android , android sdk , android.content.Intent

Meizu M1 E i.setType("video/*");只能选择图片,不能选择视频。

1
2
3
4
5
6
private void startSelectVideoActivity() {
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
i.setType("video/*");
startActivityForResult(i, REQUEST_CODE_SELECT_VIDEO);
overridePendingTransition(R.anim.slide_in_from_bottom, R.anim.slide_out_to_bottom);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_SELECT_VIDEO && resultCode == RESULT_OK && null != data) {
Uri selectedVideo = data.getData();
String videoPath = null;

if (selectedVideo.getScheme().equalsIgnoreCase("file")) {
videoPath = selectedVideo.getPath();
} else {
String[] filePathColumn = {MediaStore.Video.Media.DATA, MediaStore.Video.Media.DURATION};
Cursor cursor = getContentResolver().query(selectedVideo,
filePathColumn, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
videoPath = cursor.getString(columnIndex);
//duration = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));
cursor.close();
}
}

返回的 data 是 uri,但是这个 uri 需要解析下(content:// file://)
选择一个视频文件,大部分手机返回的是 file:// 但是锤子手机返回的是 content://

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

public static String getPath(Context context,Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final 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(context, 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(context, contentUri, selection, selectionArgs);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}

123…6

wxiang

音视频、Android、C/C++

54 日志
37 分类
43 标签
© 2019 wxiang
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.2