├── settings.gradle
├── .gitignore
└── app
├── libs
└── glide-3.6.1.jar
├── src
└── main
│ ├── res
│ ├── drawable
│ │ └── logo.png
│ ├── raw
│ │ ├── bubble_mould.png
│ │ ├── sakura_leave.png
│ │ └── faq
│ ├── values
│ │ ├── colors.xml
│ │ ├── attrs.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ └── arrays.xml
│ ├── xml
│ │ ├── livesetting.xml
│ │ ├── provider_paths.xml
│ │ ├── duang.xml
│ │ ├── circle_setting.xml
│ │ └── setting.xml
│ ├── layout
│ │ ├── color_picker.xml
│ │ ├── seekbar_preference.xml
│ │ └── seekbar_preference_material.xml
│ ├── values-v19
│ │ └── styles.xml
│ ├── values-v20
│ │ └── styles.xml
│ └── values-v21
│ │ └── styles.xml
│ ├── java
│ └── com
│ │ └── moe
│ │ └── LiveVisualizer
│ │ ├── internal
│ │ ├── OnColorSizeChangedListener.java
│ │ ├── ShadowDrawable.java
│ │ ├── VideoThread.java
│ │ ├── VisualizerThread.java
│ │ └── ImageDraw.java
│ │ ├── duang
│ │ ├── Hanabi.java
│ │ ├── MeteorShower.java
│ │ ├── Image.java
│ │ ├── Rain.java
│ │ ├── Sakura.java
│ │ ├── Bubble.java
│ │ ├── Duang.java
│ │ ├── Graph.java
│ │ ├── Snow.java
│ │ └── Engine.java
│ │ ├── inter
│ │ └── Draw.java
│ │ ├── adapter
│ │ └── ColorAdapter.java
│ │ ├── utils
│ │ ├── ColorList.java
│ │ ├── BitmapUtils.java
│ │ └── PreferencesUtils.java
│ │ ├── service
│ │ ├── CircleSwitch.java
│ │ └── SharedPreferences.java
│ │ ├── app
│ │ ├── ColorDialog.java
│ │ └── Application.java
│ │ ├── activity
│ │ ├── CrashActivity.java
│ │ ├── CropActivity.java
│ │ ├── SettingActivity.java
│ │ └── ColorListActivity.java
│ │ ├── preference
│ │ ├── ColorPickerPreference.java
│ │ └── SeekBarPreference.java
│ │ ├── widget
│ │ └── PopupLayout.java
│ │ ├── draw
│ │ ├── line
│ │ │ ├── BlockBreakerDraw.java
│ │ │ ├── RadialDraw.java
│ │ │ ├── SquareDraw.java
│ │ │ ├── YamaLineDraw.java
│ │ │ ├── PopCircleDraw.java
│ │ │ └── LineChartDraw.java
│ │ ├── circle
│ │ │ ├── CircleDisperseDraw.java
│ │ │ ├── UnKnow3.java
│ │ │ ├── UnKnow1.java
│ │ │ ├── CircleRadialDraw.java
│ │ │ ├── UnKnow2.java
│ │ │ ├── HeartDraw.java
│ │ │ ├── CircleTriangleDraw.java
│ │ │ ├── CenterRadialDraw.java
│ │ │ ├── RippleDraw.java
│ │ │ └── RingDraw.java
│ │ ├── CircleDraw.java
│ │ ├── LineDraw.java
│ │ └── Draw.java
│ │ ├── database
│ │ └── MoeData.java
│ │ └── fragment
│ │ ├── DuangSettingFragment.java
│ │ └── CircleSettingFragment.java
│ └── AndroidManifest.xml
├── proguard-rules.pro
└── build.gradle
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | gen/
3 | libs/*/*.so
4 |
5 |
--------------------------------------------------------------------------------
/app/libs/glide-3.6.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dorobonneko/wallpaper/HEAD/app/libs/glide-3.6.1.jar
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dorobonneko/wallpaper/HEAD/app/src/main/res/drawable/logo.png
--------------------------------------------------------------------------------
/app/src/main/res/raw/bubble_mould.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dorobonneko/wallpaper/HEAD/app/src/main/res/raw/bubble_mould.png
--------------------------------------------------------------------------------
/app/src/main/res/raw/sakura_leave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dorobonneko/wallpaper/HEAD/app/src/main/res/raw/sakura_leave.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #50000000
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/livesetting.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 壁纸频谱
5 | Hello world!
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/internal/OnColorSizeChangedListener.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.internal;
2 |
3 | public abstract interface OnColorSizeChangedListener
4 | {
5 | void onColorSizeChanged();
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/color_picker.xml:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v19/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v20/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/duang/Hanabi.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.duang;
2 | import android.util.DisplayMetrics;
3 | import android.graphics.Canvas;
4 | import java.util.Random;
5 |
6 | public class Hanabi extends Duang
7 | {
8 |
9 |
10 | @Override
11 | public void draw(Canvas canvas)
12 | {
13 | // TODO: Implement this method
14 | }
15 |
16 | @Override
17 | public void random(Random random)
18 | {
19 | // TODO: Implement this method
20 | }
21 |
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/duang/MeteorShower.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.duang;
2 | import android.util.DisplayMetrics;
3 | import android.graphics.Canvas;
4 | import java.util.Random;
5 |
6 | public class MeteorShower extends Duang
7 | {
8 |
9 |
10 | @Override
11 | public void draw(Canvas canvas)
12 | {
13 | // TODO: Implement this method
14 | }
15 |
16 | @Override
17 | public void random(Random random)
18 | {
19 | // TODO: Implement this method
20 | }
21 |
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\tools\adt-bundle-windows-x86_64-20131030\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/internal/ShadowDrawable.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.internal;
2 | import android.graphics.drawable.Drawable;
3 | import android.graphics.Canvas;
4 | import android.graphics.ColorFilter;
5 | import android.graphics.PixelFormat;
6 | import android.graphics.Paint;
7 | import android.graphics.Rect;
8 |
9 | public class ShadowDrawable extends Drawable
10 | {
11 | private Paint paint=new Paint();
12 | public ShadowDrawable(){
13 | paint.setColor(0xffffffff);
14 | paint.setShadowLayer(15,0,15,0xff000000);
15 | }
16 | @Override
17 | public void draw(Canvas p1)
18 | {
19 | //p1.drawColor(0xffffffff);
20 | }
21 |
22 | @Override
23 | public void setAlpha(int p1)
24 | {
25 | paint.setAlpha(p1);
26 | }
27 |
28 | @Override
29 | public void setColorFilter(ColorFilter p1)
30 | {
31 | paint.setColorFilter(p1);
32 | }
33 |
34 | @Override
35 | public int getOpacity()
36 | {
37 | // TODO: Implement this method
38 | return PixelFormat.TRANSLUCENT;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 21
5 | buildToolsVersion "21.1.0"
6 |
7 | defaultConfig {
8 | applicationId "com.moe.LiveVisualizer"
9 | minSdkVersion 15
10 | targetSdkVersion 27
11 | versionCode 81
12 | versionName "4.3"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | //compile 'com.plattysoft.leonids:LeonidsLib:+'
24 | //compile 'com.tencent.bugly:crashreport:+'
25 | //compile 'com.github.bumptech.glide:gifdecoder:+'
26 | //compile 'pl.droidsonroids.gif:android-gif-drawable:+'
27 | //compile 'com.android.support:support-core-utils:24+'
28 | //compile 'com.android.support:palette-v7:25+'
29 | //compile 'com.android.support:support-vector-drawable:25+'
30 | //compile 'com.android.support:support-media-compat:25+'
31 | compile fileTree(dir: 'libs', include: ['*.jar'])
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
17 |
21 |
25 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/inter/Draw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.inter;
2 | import android.graphics.Canvas;
3 | import android.graphics.Shader;
4 | import com.moe.LiveVisualizer.service.LiveWallpaper;
5 | import android.graphics.Matrix;
6 | import android.graphics.Paint;
7 |
8 | public interface Draw
9 | {
10 |
11 | boolean isFinalized();
12 |
13 | void finalized();
14 |
15 | void draw(Canvas canvas);
16 | void onDraw(Canvas canvas,int color_mode)throws NullPointerException;
17 | void drawGraph(double[] buffer,Canvas canvas,int color_mode,boolean useMode)throws NullPointerException;
18 | double[] getFft();
19 | byte[] getWave();
20 | //float getDownSpeed();
21 |
22 | LiveWallpaper.WallpaperEngine getEngine();
23 | void onBorderWidthChanged(int width);
24 | void onBorderHeightChanged(int height);
25 | void onSpaceWidthChanged(int space);
26 | void onDrawHeightChanged(float height);
27 | int size();
28 | int getColor();
29 | //void setShader(Shader shader);
30 | Shader getShader();
31 | void setRound(boolean round);
32 | //void setCutImage(boolean cut);
33 | //Matrix getCenterScale();
34 | void setOffsetX(int x);
35 | void setOffsetY(int y);
36 | void notifySizeChanged();
37 | float getInterpolator(float interpolator);
38 | void checkMode(int mode,Paint paint);
39 | void setAntialias(boolean antialias);
40 | void setNum(int num);
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/adapter/ColorAdapter.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.adapter;
2 | import android.widget.BaseAdapter;
3 | import android.view.ViewGroup;
4 | import android.view.View;
5 | import com.moe.LiveVisualizer.utils.ColorList;
6 | import android.view.LayoutInflater;
7 | import android.widget.TextView;
8 | import android.graphics.Color;
9 |
10 | public class ColorAdapter extends BaseAdapter
11 | {
12 | private ColorList list;
13 | public ColorAdapter(ColorList list){
14 | this.list=list;
15 | }
16 | @Override
17 | public int getCount()
18 | {
19 | // TODO: Implement this method
20 | return list.size();
21 | }
22 |
23 | @Override
24 | public Object getItem(int p1)
25 | {
26 | return list.get(p1);
27 | }
28 |
29 | @Override
30 | public long getItemId(int p1)
31 | {
32 | return p1;
33 | }
34 |
35 | @Override
36 | public View getView(int p1, View p2, ViewGroup p3)
37 | {
38 | View view;
39 | if(p2!=null)
40 | view=p2;
41 | else
42 | view=LayoutInflater.from(p3.getContext()).inflate(android.R.layout.simple_list_item_1,p3,false);
43 | TextView text=(TextView) view;
44 | text.setTextColor(list.get(p1));
45 | final float[] hsv=new float[3];
46 | Color.colorToHSV(list.get(p1),hsv);
47 | text.setText("HSV:"+hsv[0]+" "+hsv[1]+" "+hsv[2]+" #"+Integer.toHexString(list.get(p1)).toUpperCase());
48 | return view;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/utils/ColorList.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.utils;
2 | import java.util.List;
3 | import java.util.Collection;
4 | import java.util.Iterator;
5 | import java.util.ListIterator;
6 | import java.util.Set;
7 | import java.util.Arrays;
8 |
9 | public class ColorList
10 | {
11 | private int[] buffer;
12 | private int capacity=7;
13 | private int size;
14 | public ColorList(){
15 | buffer=new int[capacity];
16 | }
17 |
18 | public synchronized int getRandom()
19 | {
20 | return get((int)(Math.random()*size));
21 | }
22 | public synchronized int size()
23 | {
24 | return size;
25 | }
26 |
27 | public synchronized boolean isEmpty()
28 | {
29 | return size==0;
30 | }
31 |
32 | public synchronized int[] toArray()
33 | {
34 | return Arrays.copyOf(buffer,size);
35 | }
36 | public synchronized int get(int index){
37 | return buffer[index];
38 | }
39 | public synchronized boolean add(int p1)
40 | {
41 | buffer[size]=p1;
42 | size++;
43 | trim();
44 | return true;
45 | }
46 |
47 | public synchronized boolean remove(int index)
48 | {
49 | for(;index=buffer.length-1){
63 | int[] src=buffer;
64 | buffer=new int[src.length+(int)(capacity*0.5f)];
65 | System.arraycopy(src,0,buffer,0,size);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/duang.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
16 |
22 |
28 |
34 |
40 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/service/CircleSwitch.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.service;
2 | import android.service.quicksettings.TileService;
3 | import android.content.SharedPreferences;
4 | import android.service.quicksettings.Tile;
5 |
6 | public class CircleSwitch extends TileService
7 | {
8 | private SharedPreferences moe;
9 |
10 | @Override
11 | public void onCreate()
12 | {
13 | super.onCreate();
14 | moe=getSharedPreferences("moe",0);
15 | }
16 |
17 | @Override
18 | public void onTileAdded()
19 | {
20 | Tile tile=getQsTile();
21 | if(tile!=null){
22 | tile.setLabel(moe.getBoolean("circleSwitch",true)?"旋转开启":"旋转关闭");
23 | tile.setState(Tile.STATE_ACTIVE);
24 | tile.updateTile();
25 | }
26 | }
27 |
28 | @Override
29 | public void onTileRemoved()
30 | {
31 | Tile tile=getQsTile();
32 | if(tile!=null){
33 | tile.setLabel(moe.getBoolean("circleSwitch",true)?"旋转开启":"旋转关闭");
34 | tile.setState(Tile.STATE_INACTIVE);
35 | tile.updateTile();
36 | }
37 | }
38 |
39 | @Override
40 | public void onClick()
41 | {
42 | moe.edit().putBoolean("circleSwitch",!moe.getBoolean("circleSwitch",true)).commit();
43 | Tile tile=getQsTile();
44 | if(tile!=null){
45 | tile.setLabel(moe.getBoolean("circleSwitch",true)?"旋转开启":"旋转关闭");
46 | tile.setState(Tile.STATE_ACTIVE);
47 | tile.updateTile();
48 | }
49 | }
50 |
51 | @Override
52 | public void onStartListening()
53 | {
54 | onTileAdded();
55 | }
56 |
57 | @Override
58 | public void onStopListening()
59 | {
60 | // TODO: Implement this method
61 | super.onStopListening();
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/app/ColorDialog.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.app;
2 | import android.app.DialogFragment;
3 | import android.view.View;
4 | import android.view.LayoutInflater;
5 | import android.view.ViewGroup;
6 | import android.os.Bundle;
7 | import com.moe.LiveVisualizer.widget.ColorPickerView;
8 | import android.view.WindowManager;
9 | import android.view.Window;
10 | import android.app.Dialog;
11 | import com.moe.LiveVisualizer.R;
12 |
13 | public class ColorDialog extends DialogFragment implements ColorPickerView.OnColorCheckedListener
14 | {
15 | public ColorPickerView.OnColorCheckedListener l;
16 | @Override
17 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
18 | {
19 | // TODO: Implement this method
20 | return inflater.inflate(R.layout.color_picker,container,false);
21 | }
22 |
23 | @Override
24 | public void onViewCreated(View view, Bundle savedInstanceState)
25 | {
26 | ColorPickerView picker=(ColorPickerView) view;
27 | picker.setOnColorCheckedListener(this);
28 | super.onViewCreated(view, savedInstanceState);
29 | }
30 |
31 | @Override
32 | public void onColorChecked(int color)
33 | {
34 | if(l!=null)l.onColorChecked(color);
35 | }
36 |
37 | @Override
38 | public Dialog onCreateDialog(Bundle savedInstanceState)
39 | {
40 | // TODO: Implement this method
41 | Dialog d= super.onCreateDialog(savedInstanceState);
42 | d.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
43 |
44 | return d;
45 | }
46 |
47 |
48 | public void setOnColorCheckedListener(ColorPickerView.OnColorCheckedListener l){
49 | this.l=l;
50 | }
51 |
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/circle_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
17 |
22 |
27 |
32 |
37 |
38 |
43 |
49 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/duang/Image.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.duang;
2 | import java.util.Random;
3 | import android.graphics.Canvas;
4 | import android.graphics.Matrix;
5 | import android.util.DisplayMetrics;
6 | import android.graphics.Bitmap;
7 |
8 | public class Image extends Duang
9 | {
10 | private Matrix matrix;
11 | private float speed,wind;
12 | public Image(){
13 | matrix=new Matrix();
14 | }
15 |
16 | @Override
17 | public void draw(Canvas canvas)
18 | {
19 | if(getOffsetX()>getMaxWidth()+getSize()||getOffsetY()>getMaxHeight()+getSize()){
20 | matrix.postTranslate(-getOffsetX(),-getOffsetY());
21 | setOffsetX(getRandom().nextInt((int)(getMaxWidth()-getSize())));
22 | setOffsetY(-getSize());
23 | matrix.postTranslate(getOffsetX(),getOffsetY());
24 | }else if(getOffsetY()>-getSize()){
25 | setOffsetX(getOffsetX()+wind);
26 | setOffsetY(getOffsetY()+speed);
27 | matrix.postTranslate(wind,speed);
28 | canvas.drawBitmap(getEngine().getBuffer(),matrix,null);
29 | }else {
30 | setOffsetY(getOffsetY()+speed);
31 | matrix.postTranslate(0,speed);
32 | }
33 | }
34 |
35 | @Override
36 | public void random(Random random)
37 | {
38 | setOffsetX(random.nextInt((int)(getMaxWidth()-getSize())));
39 | if(isFirst())
40 | setOffsetY(-random.nextInt(getMaxHeight()));
41 | else
42 | setOffsetY(-getSize());
43 | speed=getSize()/getMaxSize()*getSpeed()/5+1;
44 | wind=random.nextFloat()*getWind();
45 | Bitmap bitmap=getEngine().getBuffer();
46 | if(bitmap!=null){
47 | float scale=getSize()/bitmap.getWidth();
48 | matrix.postScale(scale,scale);
49 | }matrix.postTranslate(getOffsetX(),getOffsetY());
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/activity/CrashActivity.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.activity;
2 | import android.app.Activity;
3 | import android.os.Bundle;
4 | import android.view.Menu;
5 | import android.view.MenuItem;
6 | import android.widget.TextView;
7 | import android.content.Intent;
8 | import android.text.method.ArrowKeyMovementMethod;
9 | import android.net.Uri;
10 | import android.content.ClipboardManager;
11 | import android.content.pm.PackageManager.NameNotFoundException;
12 | import android.content.pm.PackageManager;
13 | import android.os.Build;
14 |
15 | public class CrashActivity extends Activity
16 | {
17 | StringBuffer sb;
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState)
20 | {
21 | // TODO: Implement this method
22 | super.onCreate(savedInstanceState);
23 | TextView tv=new TextView(this);
24 | tv.setText(getIntent().getStringExtra(Intent.EXTRA_TEXT));
25 | sb= new StringBuffer(tv.getText());
26 | tv.setMovementMethod(new ArrowKeyMovementMethod());
27 | tv.setFitsSystemWindows(true);
28 | tv.setTextColor(0xffffffff);
29 | setContentView(tv);
30 | }
31 |
32 | @Override
33 | public boolean onCreateOptionsMenu(Menu menu)
34 | {
35 | MenuItem item=menu.add(0,0,0,"发送给开发者");
36 | item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
37 | return true;
38 | }
39 |
40 | @Override
41 | public boolean onOptionsItemSelected(MenuItem item)
42 | {
43 | ((ClipboardManager)getSystemService(CLIPBOARD_SERVICE)).setText(sb.insert(0, "@千羽樱 ").toString());
44 | Intent intent=new Intent(Intent.ACTION_VIEW);
45 | intent.setData(Uri.parse("https://www.coolapk.com/apk/com.moe.LiveVisualizer"));
46 | startActivity(intent);
47 | return true;
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/service/SharedPreferences.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.service;
2 | import android.content.ContentProvider;
3 | import android.net.Uri;
4 | import android.content.ContentValues;
5 | import android.database.Cursor;
6 | import android.database.sqlite.SQLiteOpenHelper;
7 | import android.database.sqlite.SQLiteDatabase;
8 | import com.moe.LiveVisualizer.database.MoeData;
9 |
10 | public class SharedPreferences extends ContentProvider
11 | {
12 | public static final String URI="content://moe/moe";
13 | private MoeData data;
14 | @Override
15 | public boolean onCreate()
16 | {
17 | data=new MoeData(getContext());
18 | return true;
19 | }
20 |
21 | @Override
22 | public void shutdown()
23 | {
24 | // TODO: Implement this method
25 | super.shutdown();
26 | data.close();
27 | }
28 |
29 | @Override
30 | public Cursor query(Uri p1, String[] p2, String p3, String[] p4, String p5)
31 | {
32 | return data.query(p1.getQueryParameter("key"));
33 | }
34 |
35 | @Override
36 | public String getType(Uri p1)
37 | {
38 | // TODO: Implement this method
39 | return null;
40 | }
41 |
42 | @Override
43 | public Uri insert(Uri p1, ContentValues p2)
44 | {
45 | data.insert(p1.getQueryParameter("key"),p1.getQueryParameter("value"));
46 | return p1;
47 | }
48 |
49 | @Override
50 | public int delete(Uri p1, String p2, String[] p3)
51 | {
52 | getContext().getContentResolver().notifyChange(p1,null);
53 | return data.delete(p1.getQueryParameter("key"));
54 | }
55 |
56 | @Override
57 | public int update(Uri p1, ContentValues p2, String p3, String[] p4)
58 | {
59 | getContext().getContentResolver().notifyChange(p1,null);
60 | return data.update(p1.getQueryParameter("key"),p1.getQueryParameter("value"));
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/preference/ColorPickerPreference.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.preference;
2 | import android.preference.Preference;
3 | import android.util.AttributeSet;
4 | import android.content.Context;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.content.SharedPreferences;
8 | import android.app.AlertDialog;
9 | import com.moe.LiveVisualizer.widget.ColorPickerView;
10 | import android.view.LayoutInflater;
11 | import com.moe.LiveVisualizer.R;
12 | import android.preference.ListPreference;
13 |
14 | public class ColorPickerPreference extends Preference implements ColorPickerView.OnColorCheckedListener
15 | {
16 | private AlertDialog dialog;
17 | private SharedPreferences moe;
18 | public ColorPickerPreference(Context context,AttributeSet attrs){
19 | super(context,attrs);
20 | moe=context.getSharedPreferences("moe",0);
21 | }
22 |
23 | @Override
24 | protected void onBindView(View view)
25 | {
26 | super.onBindView(view);
27 | View v=view.findViewById(android.R.id.widget_frame);
28 | ViewGroup.LayoutParams param=v.getLayoutParams();
29 | param.width=50;
30 | param.height=50;
31 | v.setLayoutParams(param);
32 | v.setVisibility(v.VISIBLE);
33 | v.setBackgroundColor(moe.getInt("color",0xff39c5bb));
34 | }
35 |
36 | @Override
37 | protected void onClick()
38 | {
39 | if(dialog==null){
40 | ColorPickerView picker=(ColorPickerView)LayoutInflater.from(getContext()).inflate(R.layout.color_picker,null);
41 | picker.setOnColorCheckedListener(this);
42 | dialog=new AlertDialog.Builder(getContext()).setView(picker).create();
43 | }
44 | dialog.show();
45 | /**/
46 | }
47 |
48 | @Override
49 | public void onColorChecked(int color)
50 | {
51 | if(shouldPersist()&&callChangeListener(color)){
52 | persistInt(color);
53 | }
54 | }
55 |
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/duang/Rain.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.duang;
2 | import android.util.DisplayMetrics;
3 | import android.graphics.Canvas;
4 | import java.util.Random;
5 | import android.graphics.Paint;
6 |
7 | public class Rain extends Duang
8 | {
9 | private Paint paint;
10 | private float[] point;
11 | private float speed;
12 | public Rain (){
13 | point=new float[4];
14 | paint=new Paint();
15 | paint.setColor(0xffffffff);
16 | }
17 |
18 | @Override
19 | public void draw(Canvas canvas)
20 | {
21 | if(getOffsetY()>getMaxHeight()||getOffsetX()<=0||getOffsetX()>getMaxWidth())
22 | {
23 | setOffsetX(getRandom().nextInt(getMaxWidth()));
24 | setOffsetY(-getSize());
25 | }else if(getOffsetY()<0){
26 | setOffsetY(getOffsetY()+speed);
27 | }else{
28 | setOffsetY(getOffsetY()+speed);
29 | canvas.drawLines(point,paint);
30 | }
31 |
32 | }
33 |
34 | @Override
35 | public void random(Random random)
36 | {
37 | paint.setStrokeWidth(random.nextFloat()*2+3);
38 | setOffsetX(random.nextInt(getMaxWidth()));
39 | //setSize(random.nextFloat()*(getMaxSize()-getMinSize())+getMinSize());
40 | if(isFirst())
41 | setOffsetY(-random.nextInt(getMaxHeight()));
42 | else
43 | setOffsetY(-getSize());
44 | speed=getSize()/getMaxSize()*getSpeed()+1;
45 |
46 | }
47 |
48 | @Override
49 | protected void setOffsetX(float offsetX)
50 | {
51 | point[0]=offsetX;
52 | point[2]=offsetX;
53 | }
54 |
55 | @Override
56 | protected void setOffsetY(float offsetY)
57 | {
58 | point[1]=offsetY;
59 | point[3]=getOffsetY()-getSize();
60 | }
61 |
62 | @Override
63 | public float getOffsetX()
64 | {
65 | // TODO: Implement this method
66 | return point[0];
67 | }
68 |
69 | @Override
70 | public float getOffsetY()
71 | {
72 | // TODO: Implement this method
73 | return point[1];
74 | }
75 |
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/widget/PopupLayout.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.widget;
2 | import android.view.ViewGroup;
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.graphics.Canvas;
6 | import android.graphics.Paint;
7 | import android.util.TypedValue;
8 |
9 | public class PopupLayout extends ViewGroup
10 | {
11 | private Paint paint;
12 | private int padding=15;
13 | public PopupLayout(Context context){
14 | super(context);
15 | padding=(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,5,getResources().getDisplayMetrics());
16 | setPadding(padding,padding,padding,padding);
17 | paint=new Paint();
18 | paint.setColor(0xffffffff);
19 | paint.setShadowLayer(padding/2.0f,0,0,0xaa000000);
20 | setWillNotDraw(false);
21 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB)
22 | setLayerType(View.LAYER_TYPE_SOFTWARE,null);
23 | }
24 |
25 | @Override
26 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
27 | {
28 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
29 | int height=0;
30 | for(int i=0;igetMaxWidth()+getSize()||getOffsetY()>getMaxHeight()+getSize()){
24 | matrix.postTranslate(-getOffsetX(),-getOffsetY());
25 | setOffsetX(getRandom().nextInt((int)(getMaxWidth()-getSize())));
26 | setOffsetY(-getSize());
27 | matrix.postTranslate(getOffsetX(),getOffsetY());
28 | }else if(getOffsetY()>-getSize()){
29 | setOffsetX(getOffsetX()+wind);
30 | setOffsetY(getOffsetY()+speed);
31 | matrix.postTranslate(wind,speed);
32 | canvas.drawBitmap(getEngine().getBuffer(),matrix,null);
33 | }else {
34 | setOffsetY(getOffsetY()+speed);
35 | matrix.postTranslate(0,speed);
36 | }
37 | }
38 |
39 | @Override
40 | public void random(Random random)
41 | {
42 | setOffsetX(random.nextInt((int)(getMaxWidth()-getSize())));
43 | if(isFirst())
44 | setOffsetY(-random.nextInt(getMaxHeight()));
45 | else
46 | setOffsetY(-getSize());
47 | speed=getSize()/getMaxSize()*getSpeed()/5+1;
48 | wind=random.nextFloat()*getWind();
49 | camera.save();
50 | camera.rotateX(random.nextInt(360));
51 | camera.rotateY(random.nextInt(360));
52 | camera.rotateZ(random.nextInt(360));
53 | camera.getMatrix(matrix);
54 | camera.restore();
55 | Bitmap bitmap=getEngine().getBuffer();
56 | if(bitmap!=null){
57 | float scale=getSize()/bitmap.getWidth();
58 | matrix.postScale(scale,scale);
59 | }matrix.postTranslate(getOffsetX(),getOffsetY());
60 | }
61 |
62 |
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/utils/BitmapUtils.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.utils;
2 | import android.graphics.Bitmap;
3 | import android.graphics.Matrix;
4 | import android.renderscript.RenderScript;
5 | import android.renderscript.Allocation;
6 | import android.renderscript.ScriptIntrinsicBlur;
7 | import android.content.Context;
8 | import android.renderscript.Element;
9 |
10 | public class BitmapUtils
11 | {
12 | public static Bitmap scale(Bitmap bit,float scaleX,float scaleY){
13 | if(bit==null)return null;
14 | Matrix matrix=new Matrix();
15 | matrix.postScale(scaleX,scaleY);
16 | Bitmap buffer=Bitmap.createBitmap(bit,0,0,bit.getWidth(),bit.getHeight(),matrix,true);
17 | return buffer;
18 | }
19 | public static Bitmap scaleWithSize(Bitmap bit,int width,int height){
20 | if(bit==null)return null;
21 | float scaleX=((float)width)/bit.getWidth();
22 | float scaleY=((float)height)/bit.getHeight();
23 | if(scaleX==1&&scaleY==1)return bit;
24 | return scale(bit,scaleX,scaleY);
25 | }
26 | public static Bitmap blur(Context context,Bitmap bit){
27 | if(bit==null)return null;
28 | RenderScript rs=RenderScript.create(context);
29 | Bitmap blurredBitmap =BitmapUtils.scaleWithSize(bit,bit.getWidth()/4,bit.getHeight()/4);
30 |
31 | final Allocation input = Allocation.createFromBitmap(rs,blurredBitmap,Allocation.MipmapControl.MIPMAP_FULL,Allocation.USAGE_SHARED);
32 | final Allocation output = Allocation.createTyped(rs,input.getType());
33 | //(3)
34 | // Load up an instance of the specific script that we want to use.
35 | ScriptIntrinsicBlur scriptIntrinsicBlur = ScriptIntrinsicBlur.create(rs,Element.U8_4(rs));
36 | //(4)
37 | scriptIntrinsicBlur.setInput(input);
38 | //(5)
39 | // Set the blur radius
40 | scriptIntrinsicBlur.setRadius(25);
41 | //(6)
42 | // Start the ScriptIntrinisicBlur
43 | scriptIntrinsicBlur.forEach(output);
44 | //(7)
45 | // Copy the output to the blurred bitmap
46 | output.copyTo(blurredBitmap);
47 | //(8)
48 | rs.destroy();
49 | return blurredBitmap;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/line/BlockBreakerDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.line;
2 | import com.moe.LiveVisualizer.draw.LineDraw;
3 | import com.moe.LiveVisualizer.internal.ImageDraw;
4 | import com.moe.LiveVisualizer.service.LiveWallpaper;
5 | import android.graphics.Canvas;
6 | import android.graphics.Paint;
7 | import android.graphics.PorterDuff;
8 | import android.graphics.PorterDuffXfermode;
9 | import com.moe.LiveVisualizer.utils.ColorList;
10 |
11 | public class BlockBreakerDraw extends LineDraw
12 | {
13 | private float[] points,breaker;
14 | public BlockBreakerDraw(ImageDraw draw)
15 | {
16 | super(draw);
17 | }
18 |
19 | @Override
20 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
21 | {
22 | Paint paint=getPaint();
23 | if (points == null || points.length != size())
24 | {
25 | points = new float[size()];
26 | breaker = new float[points.length];
27 | }
28 | float x=getStartOffset();//起始像素
29 | final float halfWidth=getBorderWidth() / 2;
30 | for (int i=0;i < points.length;i ++)
31 | {
32 | if (useMode)
33 | checkMode(color_mode,paint);
34 | float height=(float)(buffer[i] / (double)Byte.MAX_VALUE * getBorderHeight());
35 | if (height < points[i])
36 | points[i]=Math.max(0,points[i]-(points[i]-height)*getInterpolator((points[i]-height)/points[i]*0.99f));
37 | else if(height>points[i]){
38 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height*0.79f);
39 | }
40 | if (height < breaker[i])
41 | breaker[i] =Math.max(0,breaker[i]-(breaker[i]-height)*getInterpolator((breaker[i]-height)/breaker[i]*0.89f)*0.65f);
42 | else if(height>breaker[i])
43 | breaker[i]=points[i];
44 | canvas.drawRect(x, getDrawHeight() - points[i], x + getBorderWidth() , getDrawHeight(), paint);
45 | canvas.drawRect(x, getDrawHeight() - breaker[i] - halfWidth, x + getBorderWidth() , getDrawHeight() - breaker[i], paint);
46 | x += getSpaceWidth();
47 | }
48 |
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/app/Application.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.app;
2 | import java.io.FileOutputStream;
3 | import java.io.FileNotFoundException;
4 | import java.io.IOException;
5 | import java.lang.reflect.Method;
6 | import java.lang.reflect.Proxy;
7 | import android.content.res.Resources;
8 | import java.lang.reflect.InvocationHandler;
9 | import com.moe.LiveVisualizer.R;
10 | import android.content.Intent;
11 | import com.moe.LiveVisualizer.activity.CrashActivity;
12 | import android.content.pm.PackageManager.NameNotFoundException;
13 | import android.content.pm.PackageManager;
14 | import android.os.Build;
15 |
16 | public class Application extends android.app.Application implements Thread.UncaughtExceptionHandler
17 | {
18 |
19 | @Override
20 | public void uncaughtException(final Thread p1,final Throwable p2)
21 | {
22 | new Thread(){
23 | public void run(){
24 | if(p2==null)return;
25 | String msg=p2.getMessage();
26 | StringBuffer sb=new StringBuffer();
27 | try
28 | {
29 | sb.append(msg);
30 | sb.append("\n").append(getPackageManager().getPackageInfo(getPackageName(), 0).versionName).append("\n").append(Build.MODEL).append(" ").append(Build.VERSION.RELEASE).append("\n");
31 | }
32 | catch (PackageManager.NameNotFoundException e)
33 | {}
34 | for (StackTraceElement element:p2.getStackTrace())
35 | sb.append("\n").append(element.toString());
36 | Intent intent=new Intent(getApplicationContext(),CrashActivity.class);
37 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
38 | intent.putExtra(Intent.EXTRA_TEXT,sb.toString());
39 | startActivity(intent);
40 | }
41 | }.start();
42 | try
43 | {
44 | Thread.sleep(3000);
45 | }
46 | catch (InterruptedException e)
47 | {}
48 | android.os.Process.killProcess(android.os.Process.myPid());
49 | }
50 |
51 |
52 | @Override
53 | public void onCreate()
54 | {
55 | super.onCreate();
56 | //Bugly.init(this,"39c93f2bb3",false);
57 | Thread.currentThread().setUncaughtExceptionHandler(this);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/database/MoeData.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.database;
2 | import android.database.sqlite.SQLiteOpenHelper;
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.database.Cursor;
6 | import android.database.sqlite.SQLiteStatement;
7 |
8 | public class MoeData extends SQLiteOpenHelper
9 | {
10 | public MoeData(Context context){
11 | super(context,"moe",null,3);
12 | }
13 |
14 | public int update(String key, String value)
15 | {
16 | Cursor c=query(key);
17 | if(c.getCount()==0)
18 | insert(key,value);
19 | else{
20 | SQLiteDatabase sql=getReadableDatabase();
21 | SQLiteStatement state=sql.compileStatement("update moe set value=? where key=?");
22 | state.bindAllArgsAsStrings(new String[]{value,key});
23 | state.executeUpdateDelete();
24 | state.close();
25 | //sql.close();
26 | }
27 | return 1;
28 | }
29 |
30 | public int delete(String key)
31 | {
32 | SQLiteDatabase sql=getReadableDatabase();
33 | SQLiteStatement state=sql.compileStatement("delete from moe where key=?");
34 | state.bindAllArgsAsStrings(new String[]{key});
35 | state.executeUpdateDelete();
36 | state.close();
37 | //sql.close();
38 | return 1;
39 | }
40 |
41 | public Cursor query(String key)
42 | {
43 | SQLiteDatabase sql=getReadableDatabase();
44 | synchronized(sql){
45 | return sql.query("moe",null,"key=?",new String[]{key},null,null,null);
46 | }
47 | }
48 |
49 | public void insert(String key, String value)
50 | {
51 | SQLiteDatabase sql=getReadableDatabase();
52 | SQLiteStatement state=sql.compileStatement("insert into moe values(?,?)");
53 | state.bindAllArgsAsStrings(new String[]{key,value});
54 | state.executeUpdateDelete();
55 | state.close();
56 | //sql.close();
57 | }
58 |
59 | @Override
60 | public void onCreate(SQLiteDatabase p1)
61 | {
62 | p1.execSQL("create table moe(key TEXT primary key,value TEXT)");
63 | }
64 |
65 | @Override
66 | public void onUpgrade(SQLiteDatabase p1, int p2, int p3)
67 | {
68 | // TODO: Implement this method
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/res/raw/faq:
--------------------------------------------------------------------------------
1 | 3.8.4
2 | 更改柱形图显示效果,支持涟漪动画(网上找的,效果不是很好
3 | 3.8.3
4 | 支持水平或垂直翻转
5 | 3.8.2
6 | 修复设置折线图崩溃bug,优化异常捕捉
7 | 3.8.1
8 | 修复多次预览黑屏bug
9 | 3.8
10 | 优化性能,更流畅的动画效果
11 | 3.7
12 | 新增一个特效
13 | 3.6.2
14 | 新的动画效果
15 | 3.6.1
16 | 完善新频谱的色彩模式
17 | 3.6
18 | 新增一种频谱
19 | 3.5.1
20 | 频谱可倒置
21 | 3.5
22 | 加入后台休眠机制,优化算法,方块频谱可调节高度
23 | 3.4
24 | 特效支持自定义图片
25 | 3.3.9
26 | 新增一种频谱(只支持间隔取色和随机颜色),bug修复
27 | 3.3.8.2
28 | 去除无用类
29 | 3.3.8.1
30 | 修正特效重叠bug,修正气泡颜色
31 | 3.3.8
32 | 气泡特效
33 | 3.3.7.1
34 | bug修复,裁剪图片时抗锯齿
35 | 3.3.7
36 | 更改数据存储方式
37 | 3.3.6.1
38 | 支持设置视频第一帧作为背景
39 | 3.3.5
40 | 新增樱花特效,优化特效算法
41 | 3.3.4
42 | 新增雨滴特效
43 | 3.3.3
44 | 更改主题,可能存在兼容性问题
45 | 3.3.2
46 | 新增屏幕特效(实验性功能)
47 | 3.3.1
48 | 新增打砖块频谱,该频谱不支持圆角
49 | 3.3
50 | 新增方块频谱
51 | 3.2.10
52 | 新增霓虹灯组色彩模式,建议清除数据再使用
53 | 3.2.9
54 | 重构部分代码,折线图使用波形数据绘制
55 | 3.2.8
56 | bug修复
57 | 3.2.7
58 | 进度条支持微调,修复进度显示错误bug
59 | 3.2.6
60 | 可更改色带渐变方向
61 | 3.2.5
62 | 修复横竖屏旋转导致线条间距变大bug
63 | 3.2.4
64 | 可更改霓虹灯变色间隔时长
65 | 3.2.3
66 | 改回对称
67 | 3.2.2
68 | 修复部分横屏bug,重新设计裁剪框生成算法,软件方向不在固定
69 | 3.1.2
70 | 加模式
71 | 3.1.1
72 | bug修复
73 | 3.1
74 | 修复中心圆裁剪bug,又写了一堆,支持横屏模式,本次改动较大,会有不少bug,请及时提交崩溃日志到评论区,点击发送日志会自动复制到剪贴板
75 | 3.0.2
76 | 修复颜色更新bug
77 | 3.0.1
78 | 修复gif动画bug,优化启动速度
79 | 3.0
80 | 自己探索
81 | 2.9.1
82 | 移除bugly,使用360加固
83 | 2.9
84 | 可对中心圆进行一些简单控制
85 | 2.8
86 | 新增两种频谱,原先的图片和颜色失效,需要重新配置
87 | 2.7.1
88 | 修复显示问题,暂时不更了,明天科目一
89 | 2.7
90 | 修复几个bug
91 | 2.6
92 | 中心图支持gif,本次改动较大,可能有明显bug
93 | 2.5
94 | 支持手输十六进制颜色代码,霓虹灯进入过渡动画
95 | 2.4
96 | 新增霓虹灯色彩模式,5s切换一次颜色
97 | 2.3
98 | 支持关闭中心图片旋转(通知栏图块),优化算法,圆形射线频谱不再掉帧
99 | 2.2
100 | 加入高帧率模式,支持调节动画速度
101 | 2.1
102 | 新增一种颜色模式,优化色带算法(圆形射线频谱除外)
103 | 2.0
104 | 加了点简单的动画
105 | 1.9
106 | 提升稳定性
107 | 1.8
108 | 重构部分代码
109 | 1.7
110 | 修复横屏选色遮挡bug,支持设置gif图作背景(不推荐使用),默认30帧刷新,当gif作背景以gif为准(最低30),使用圆环射线频谱会造成严重掉帧,了解一下
111 | 1.6
112 | 修复圆环射线相关bug,新增弹弹圈样式,移除v4,v7等兼容包
113 | 1.5
114 | 新版本需要卸载旧版本再安装
115 | 屏蔽专辑封面相关代码(测试了几款音乐软件,只有酷狗按新版标准开发,但是它不提供专辑封面,其它几款都或多或少有问题,qq音乐在后台,开关其它播放器它就会更新歌曲数据,aplayer在退出后会更新歌曲数据,网易云不会回调数据)
116 | 1.4
117 | 引入bugly,日常写bug
118 | 1.3
119 | 支持折线和圆环射线,优化兼容性
120 | 1.2
121 | 可以将专辑封面作为背景和频谱颜色(支持的播放器较少,网易云音乐支持)
122 | 1.1
123 | 支持设置静态图为背景,可更改频谱的颜色,大小,位置等
124 |
125 |
126 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/line/RadialDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.line;
2 | import android.graphics.Canvas;
3 | import android.content.SharedPreferences;
4 | import com.moe.LiveVisualizer.utils.ColorList;
5 | import com.moe.LiveVisualizer.service.LiveWallpaper;
6 | import android.graphics.Paint;
7 | import android.graphics.Bitmap;
8 | import android.graphics.PorterDuffXfermode;
9 | import android.graphics.PorterDuff;
10 | import android.util.TypedValue;
11 | import android.graphics.LinearGradient;
12 | import android.graphics.Shader;
13 | import com.moe.LiveVisualizer.internal.ImageDraw;
14 | import com.moe.LiveVisualizer.draw.CircleDraw;
15 | import com.moe.LiveVisualizer.draw.LineDraw;
16 |
17 | public class RadialDraw extends LineDraw
18 | {
19 | private float[] points;
20 | public RadialDraw(ImageDraw draw)
21 | {
22 | super(draw);
23 | }
24 |
25 | @Override
26 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
27 | {
28 | Paint paint=getPaint();
29 | if ( points == null || points.length != size() )
30 | points = new float[size()];
31 | float x=getStartOffset();//起始像素
32 | final float halfWidth=getBorderWidth()/ 2;
33 | for ( int i=0;i < points.length;i ++ )
34 | {
35 | if(useMode)
36 | checkMode(color_mode,paint);
37 | float height=(float)(buffer[i] / 127d * getBorderHeight());
38 | if ( height < points[i] )
39 | points[i]=Math.max(0,points[i]-(points[i]-height)*getInterpolator((points[i]-height)/points[i]*1.6f));
40 | else if(height>points[i])
41 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height*0.7f);
42 | if ( paint.getStrokeCap() != Paint.Cap.ROUND )
43 | {
44 | canvas.drawRect(x, getDrawHeight() - points[i], x + getBorderWidth() , getDrawHeight()+points[i], paint);
45 | x += getSpaceWidth();
46 | }
47 | else
48 | {
49 | canvas.drawLine(x + halfWidth, getDrawHeight() - points[i], x+halfWidth, getDrawHeight()+points[i], paint);
50 | //canvas.drawLine(x, getDrawHeight() + height + halfWidth, x, getDrawHeight() + halfWidth, paint);
51 | x += getSpaceWidth();
52 | }
53 |
54 | }
55 |
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/line/SquareDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.line;
2 | import com.moe.LiveVisualizer.draw.LineDraw;
3 | import com.moe.LiveVisualizer.internal.ImageDraw;
4 | import com.moe.LiveVisualizer.service.LiveWallpaper;
5 | import android.graphics.Canvas;
6 | import android.graphics.Paint;
7 | import android.graphics.RectF;
8 | import android.graphics.PorterDuff;
9 | import android.graphics.PorterDuffXfermode;
10 | import com.moe.LiveVisualizer.utils.ColorList;
11 |
12 | public class SquareDraw extends LineDraw
13 | {
14 | private float[] points;
15 | public SquareDraw(ImageDraw draw){
16 | super(draw);
17 | }
18 |
19 | private int squareSize(){
20 | return (int)(getBorderHeight()/getBorderWidth());
21 | }
22 | @Override
23 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
24 | {
25 | Paint paint=getPaint();
26 | if ( points == null || points.length != size() )
27 | points = new float[size()];
28 | float x=getStartOffset();//起始像素
29 | final float halfWidth=getBorderWidth()/8;
30 | float itemHeight=(float) Math.floor(getBorderHeight()/20f);
31 | float squareHeight=itemHeight*0.7f;
32 | for ( int i=0;i < points.length;i ++ )
33 | {
34 | if(useMode)
35 | checkMode(color_mode,paint);
36 | float height=(float)(buffer[i] / (double)Byte.MAX_VALUE * getBorderHeight());
37 | if ( height < points[i] )
38 | points[i]=Math.max(0,points[i]-(points[i]-height)*getInterpolator((points[i]-height)/points[i]*1f)*1f);
39 | else if(height>points[i])
40 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height*0.6f);
41 | float offsetLeft=x;
42 | float offsetRight=x+getBorderWidth();
43 | x+=getSpaceWidth();
44 | double size=Math.ceil(points[i]/itemHeight);
45 | for(int n=0;ngetMaxWidth()||getOffsetY()<-getSize()){
30 | matrix.postTranslate(-getOffsetX(),-getOffsetY());
31 | setOffsetY(getMaxHeight());
32 | setOffsetX(getRandom().nextInt(getMaxWidth())-getSize());
33 | matrix.postTranslate(getOffsetX(),getOffsetY());
34 | }else if(getOffsetY()height?wind:-wind);
36 | setOffsetX(getOffsetX()+offset);
37 | setOffsetY(getOffsetY()-speed);
38 | matrix.postTranslate(offset,-speed);
39 | canvas.drawBitmap(getEngine().getBuffer(),matrix,paint);
40 | }else{
41 | setOffsetY(getOffsetY()-speed);
42 | matrix.postTranslate(0,-speed);
43 | }
44 | }
45 |
46 | @Override
47 | public void random(Random random)
48 | {
49 | paint.setColorFilter(new PorterDuffColorFilter(random.nextInt(0x7f7f7f)+0x7f7f7f7f,PorterDuff.Mode.SRC_IN));
50 | setOffsetX(random.nextInt(getMaxWidth())-getSize());
51 | if(isFirst())
52 | setOffsetY(random.nextInt(getMaxHeight())+getMaxHeight());
53 | else
54 | setOffsetY(getMaxHeight());
55 | speed=getSize()/getMaxSize()*getSpeed()/5+1;
56 | wind=random.nextFloat()*getWind();
57 | if(getEngine().getBuffer()!=null)
58 | matrix.setScale(getSize()/getEngine().getBuffer().getWidth(),getSize()/getEngine().getBuffer().getHeight());
59 | matrix.postTranslate(getOffsetX(),getOffsetY());
60 | direction=random.nextBoolean();
61 | height=random.nextInt(getMaxHeight()/2)+getMaxHeight()/4;
62 | }
63 |
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - 色带渐变
5 | - 间隔取色
6 | - 随机颜色
7 | - 霓虹灯
8 | - 霓虹灯组
9 |
10 |
11 | - 柱形图
12 | - 折线图
13 | - 圆环射线
14 | - 弹弹圈
15 | - 圆环三角
16 | - 射线
17 | - 水波纹
18 | - 圆环离散点
19 | - 山坡线
20 | - 方块
21 | - 打砖块
22 | - 未命名
23 | - 未命名2
24 | - 未命名3
25 | - 心形
26 |
27 |
28 | - 0
29 | - 1
30 | - 2
31 | - 3
32 | - 4
33 |
34 |
35 | - 0
36 | - 1
37 | - 2
38 | - 3
39 | - 4
40 | - 5
41 | - 6
42 | - 7
43 | - 8
44 | - 9
45 | - 10
46 | - 11
47 | - 12
48 | - 13
49 | - 14
50 |
51 |
52 | - 向外
53 | - 向内
54 |
55 |
56 | - 0
57 | - 1
58 |
59 |
60 | - 从左至右
61 | - 从右至左
62 | - 从上至下
63 | - 从下至上
64 | - 左上至右下
65 | - 右上至左下
66 | - 左下至右上
67 | - 右下至左上
68 |
69 |
70 | - 0
71 | - 1
72 | - 2
73 | - 3
74 | - 4
75 | - 5
76 | - 6
77 | - 7
78 |
79 |
80 | - 雪花
81 | - 雨滴
82 | - 樱花
83 | - 气泡
84 | - 图片
85 | - 基本图形
86 |
87 |
88 | - 0
89 | - 1
90 | - 2
91 | - 3
92 | - 4
93 | - 5
94 |
95 |
96 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/duang/Duang.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.duang;
2 | import android.animation.TypeEvaluator;
3 | import android.graphics.Path;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import java.util.Random;
7 | import android.util.DisplayMetrics;
8 |
9 | public abstract class Duang
10 | {
11 | private float offsetX,offsetY,size;
12 | private Random random;
13 | private Engine engine;
14 | private boolean first=true;
15 | public Duang(){
16 | random=new Random(System.nanoTime());
17 | }
18 | public Random getRandom(){
19 | return random;
20 | }
21 | public boolean isFirst(){
22 | boolean flag=first;
23 | first=false;
24 | return flag;
25 | }
26 | final void setEngine(Engine engine){
27 | this.engine=engine;
28 | }
29 | public Engine getEngine(){
30 | return engine;
31 | }
32 | public int getMinSize(){
33 | return engine.getMinSize();
34 | }
35 | public int getMaxSize(){
36 | return engine.getMxSize();
37 | }
38 | public int getWind()
39 | {
40 | return engine.getWind();
41 | }
42 |
43 | public int getMaxWidth()
44 | {
45 | return getDisplay().widthPixels;
46 | }
47 |
48 |
49 | public int getMaxHeight()
50 | {
51 | return getDisplay().heightPixels;
52 | }
53 | public DisplayMetrics getDisplay(){
54 | return engine.getDisplay();
55 | }
56 | protected void setOffsetX(float offsetX)
57 | {
58 | this.offsetX = offsetX;
59 | }
60 |
61 | public float getOffsetX()
62 | {
63 | return offsetX;
64 | }
65 |
66 | protected void setOffsetY(float offsetY)
67 | {
68 | this.offsetY = offsetY;
69 | }
70 |
71 | public float getOffsetY()
72 | {
73 | return offsetY;
74 | }
75 |
76 | protected void setSize(float size)
77 | {
78 | this.size = size;
79 | }
80 |
81 | public float getSize()
82 | {
83 | return size;
84 | }
85 |
86 |
87 |
88 | public int getSpeed()
89 | {
90 | return engine.getSpeed();
91 | }
92 |
93 | public abstract void draw(Canvas canvas);
94 | public abstract void random(Random random);
95 | public void reset(boolean random){
96 | if(random){
97 | setSize(this.random.nextFloat()*(getMaxSize()-getMinSize())+getMinSize());
98 | random(this.random);
99 | }else
100 | {
101 | offsetX=0;
102 | offsetY=0;
103 | size=0;
104 | }
105 | }
106 | public void release(){
107 | reset(false);
108 | engine=null;
109 | try
110 | {
111 | finalize();
112 | }
113 | catch (Throwable e)
114 | {}
115 | }
116 |
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/internal/VideoThread.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.internal;
2 | import android.media.MediaPlayer;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.view.Surface;
5 | import android.graphics.SurfaceTexture;
6 | import android.media.MediaMetadataRetriever;
7 | import java.io.IOException;
8 | import android.graphics.Bitmap;
9 | import java.io.File;
10 | import android.media.MediaCodec;
11 | import android.graphics.BitmapFactory;
12 | import java.util.ArrayList;
13 | import android.media.MediaDataSource;
14 | import java.io.InputStream;
15 | import java.io.FileDescriptor;
16 | import java.util.Iterator;
17 | import android.graphics.Canvas;
18 | import android.graphics.Rect;
19 | import android.view.SurfaceHolder;
20 | import android.view.SurfaceHolder.Callback;
21 | import android.graphics.SurfaceTexture.OnFrameAvailableListener;
22 | import android.os.Handler;
23 | import android.view.TextureView;
24 | import java.lang.reflect.Constructor;
25 | import java.lang.reflect.InvocationTargetException;
26 | import java.lang.reflect.Proxy;
27 | import java.lang.reflect.InvocationHandler;
28 | import java.lang.reflect.Method;
29 | import java.lang.reflect.Field;
30 |
31 | public class VideoThread extends Thread
32 | {
33 | private MediaMetadataRetriever meta;
34 | private String path;
35 | private long duration,current,oldTime;
36 | private boolean playing;
37 | private ArrayList list=new ArrayList<>();
38 | public VideoThread(String path){
39 | this.path=path;
40 | meta=new MediaMetadataRetriever();
41 | }
42 |
43 | public void notifyVisiableChanged(boolean visible)
44 | {
45 | playing=visible;
46 | if(playing)
47 | oldTime=System.currentTimeMillis();
48 | }
49 |
50 | public void onSizeChanged()
51 | {
52 | // TODO: Implement this method
53 | }
54 | @Override
55 | public void run()
56 | {
57 | meta.setDataSource(path);
58 | duration=Long.parseLong(meta.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
59 | try{
60 | for(long i=0;i=list.size())
72 | current=0;
73 | Bitmap b=list.get((int)current);
74 | current++;
75 | return b;
76 | }catch(Exception e){}
77 | return null;
78 | }
79 | public void destroy(){
80 | meta.release();
81 | Iterator iterator=list.iterator();
82 | while(iterator.hasNext()){
83 | iterator.next().recycle();
84 | iterator.remove();
85 | }
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/CircleDisperseDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.SweepGradient;
7 | import android.graphics.Bitmap;
8 | import android.graphics.PorterDuffXfermode;
9 | import android.graphics.PorterDuff;
10 | import android.graphics.Shader;
11 | import android.graphics.PointF;
12 | import android.graphics.LinearGradient;
13 | import com.moe.LiveVisualizer.utils.ColorList;
14 |
15 | public class CircleDisperseDraw extends RingDraw
16 | {
17 | private float[] points;
18 |
19 | public CircleDisperseDraw(ImageDraw draw)
20 | {
21 | super(draw);
22 | }
23 |
24 | @Override
25 | public void onDraw(Canvas canvas, int color_mode)
26 | {
27 | super.onDraw(canvas,color_mode);
28 | drawCircleImage(canvas);
29 |
30 | }
31 |
32 | @Override
33 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
34 | {
35 | PointF point=getPointF();
36 | float radius=getRadius();
37 | final float radialHeight=getDirection()==OUTSIDE?getBorderHeight():getRadius();
38 | Paint paint=getPaint();
39 | paint.setStrokeWidth(getBorderWidth());
40 | if ( points == null || points.length != size() )
41 | points = new float[size()];
42 | float degress_step=360f / size();
43 | canvas.save();
44 | //final PointF center=getPointF();
45 | canvas.rotate(degress_step / 2f, point.x, point.y);
46 | for ( int i=0;i < points.length;i ++ )
47 | {
48 | if(useMode)
49 | checkMode(color_mode,paint);
50 | float height=(float) (buffer[i] / 127d * radialHeight);
51 | if ( height < points[i] )
52 | points[i]=Math.max(0,points[i]-(points[i]-height)*getInterpolator((points[i]-height)/points[i]*0.8f)*0.45f);
53 | else if(height>points[i])
54 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height);
55 | height=points[i];
56 | if(paint.getStrokeCap()==Paint.Cap.ROUND)
57 | canvas.drawLine(point.x,point.y-radius+(getDirection()==OUTSIDE?- height:height), point.x, point.y -radius+(getDirection()==OUTSIDE?- height:height), paint);
58 | else
59 | canvas.drawRect(point.x-getBorderWidth()/2, point.y -radius+(getDirection()==OUTSIDE?- height:height), point.x + getBorderWidth()/2, point.y -radius+(getDirection()==OUTSIDE?- height-getBorderWidth():height+getBorderWidth()), paint);
60 | canvas.rotate(degress_step, point.x, point.y);
61 | //degress+=degress_step;
62 | }
63 | canvas.restore();
64 | }
65 |
66 |
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/CircleDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.PointF;
7 | import android.graphics.Bitmap;
8 | import android.graphics.PorterDuffXfermode;
9 | import android.graphics.PorterDuff;
10 | import android.graphics.Matrix;
11 |
12 | public abstract class CircleDraw extends Draw
13 | {
14 | private PointF point;
15 | private boolean rotation;
16 | private int num;
17 | public CircleDraw(ImageDraw draw){
18 | super(draw);
19 | LiveWallpaper.WallpaperEngine engine=draw.getEngine();
20 | point=new PointF();
21 | point.x=engine.getPreference().getInt("offsetX",Math.min(engine.getDisplayWidth(),engine.getDisplayHeight())/2);
22 | point.y=engine.getPreference().getInt("offsetY",Math.max(engine.getDisplayHeight(),engine.getDisplayWidth())/2);
23 | num=engine.getPreference().getInt("num",50);
24 | if(engine.getDisplayWidth()>engine.getDisplayHeight()){
25 | float x=point.x;
26 | point.x=point.y;
27 | point.y=x;
28 | }
29 | }
30 |
31 | public void setVisualizerRotation(boolean rotation)
32 | {
33 | this.rotation=rotation;
34 | }
35 |
36 | @Override
37 | public void notifySizeChanged()
38 | {
39 | point.x=getEngine().getPreference().getInt("offsetX",Math.min(getEngine().getDisplayWidth(),getEngine().getDisplayHeight())/2);
40 | point.y=getEngine().getPreference().getInt("offsetY",Math.max(getEngine().getDisplayHeight(),getEngine().getDisplayWidth())/2);
41 | if(getEngine().getDisplayWidth()>getEngine().getDisplayHeight()){
42 | float x=point.x;
43 | point.x=point.y;
44 | point.y=x;
45 | }
46 | }
47 | public boolean isVisualizerRotation(){
48 | return rotation;
49 | }
50 |
51 | @Override
52 | public void setNum(int num) {
53 | this.num=num;
54 | }
55 |
56 | public int getSize(){
57 | return num;
58 | }
59 | @Override
60 | public void setOffsetX(int x)
61 | {
62 | if(getEngine().getDisplayWidth()>getEngine().getDisplayHeight())
63 | point.y=x;
64 | else
65 | point.x=x;
66 | }
67 |
68 | @Override
69 | public void setOffsetY(int y)
70 | {
71 | if(getEngine().getDisplayWidth()>getEngine().getDisplayHeight())
72 | point.x=y;
73 | else
74 | point.y=y;
75 | }
76 |
77 |
78 | @Override
79 | final public void onDrawHeightChanged(float height)
80 | {
81 | // TODO: Implement this method
82 | }
83 |
84 | public PointF getPointF(){
85 | return point;
86 | }
87 |
88 | @Override
89 | public void finalized()
90 | {
91 | // TODO: Implement this method
92 | super.finalized();
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/UnKnow3.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import android.graphics.Canvas;
4 | import com.moe.LiveVisualizer.service.LiveWallpaper;
5 | import com.moe.LiveVisualizer.utils.ColorList;
6 | import android.graphics.PointF;
7 | import android.graphics.Paint;
8 | import android.graphics.RectF;
9 | import android.graphics.Path;
10 |
11 | public class UnKnow3 extends RingDraw
12 | {
13 | private float[] points;
14 | private float width;
15 | private Path lines=new Path();
16 | public UnKnow3(ImageDraw draw){
17 | super(draw);
18 | }
19 | @Override
20 | public void onSizeChanged()
21 | {
22 | // TODO: Implement this method
23 | super.onSizeChanged();
24 | width=(float)(2*getRadius()*Math.PI/(size()-1));
25 |
26 | }
27 |
28 | @Override
29 | public void onDraw(Canvas canvas, int color_mode)
30 | {
31 | drawCircleImage(canvas);
32 | super.onDraw(canvas, color_mode);
33 | }
34 |
35 | @Override
36 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
37 | {
38 | PointF center=getPointF();
39 | Paint paint=getPaint();
40 | paint.setAntiAlias(true);
41 | paint.setStyle(Paint.Style.STROKE);
42 | paint.setStrokeWidth(getBorderWidth());
43 | paint.setStrokeCap(getRound());
44 | if(points==null||points.length!=size())
45 | points=new float[size()];
46 | canvas.save();
47 | canvas.rotate(-90,center.x,center.y);
48 | canvas.translate(center.x,center.y);
49 | double degress=2d/size()*Math.PI;
50 | /*float halfWidth=width/2;*/
51 | float halfBorder=getBorderWidth()/2f;
52 | float radius=getRadius();
53 | for(int i=0;ipoints[i])
58 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height);
59 | height=points[i];
60 | if(useMode)
61 | checkMode(color_mode,paint);
62 | double value=degress*i;
63 | lines.moveTo((float)((radius-points[i])*Math.cos(value)),(float)((radius-points[i])*Math.sin(value)));
64 | lines.lineTo((float)((radius+points[i])*Math.cos(value)),(float)((radius+points[i])*Math.sin(value)));
65 | value=degress*(i+1);
66 | lines.lineTo((float)((radius+points[i])*Math.cos(value)),(float)((radius+points[i])*Math.sin(value)));
67 | lines.lineTo((float)((radius-points[i])*Math.cos(value)),(float)((radius-points[i])*Math.sin(value)));
68 | lines.close();
69 | if(useMode){
70 | canvas.drawPath(lines,paint);
71 | lines.reset();
72 | }
73 | }
74 | if(!useMode)
75 | canvas.drawPath(lines,paint);
76 | lines.reset();
77 | canvas.restore();
78 |
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/line/YamaLineDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.line;
2 | import android.graphics.*;
3 |
4 | import android.util.TypedValue;
5 | import com.moe.LiveVisualizer.service.LiveWallpaper;
6 | import com.moe.LiveVisualizer.draw.LineDraw;
7 | import com.moe.LiveVisualizer.internal.ImageDraw;
8 | import com.moe.LiveVisualizer.utils.ColorList;
9 |
10 | public class YamaLineDraw extends LineDraw
11 | {
12 | private float[] points;
13 | public YamaLineDraw(ImageDraw draw)
14 | {
15 | super(draw);
16 | }
17 |
18 | /*@Override
19 | public void onDraw(Canvas canvas, int color_mode)
20 | {
21 | Paint paint=getPaint();
22 | switch(color_mode){
23 | case 0:
24 | switch ( getEngine().getColorList().size() )
25 | {
26 | case 0:
27 | paint.setColor(0xff39c5bb);
28 | drawGraph(getFft(), canvas, color_mode, false);
29 | break;
30 | case 1:
31 | paint.setColor(getEngine().getColorList().get(0));
32 | drawGraph(getFft(), canvas, color_mode, false);
33 | break;
34 | default:
35 | paint.setShader(getShader());
36 | drawGraph(getFft(), canvas, color_mode, false);
37 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
38 | paint.setShader(null);
39 | break;
40 | }
41 | break;
42 | case 1:
43 | case 4:
44 | case 2:
45 | drawGraph(getFft(), canvas, color_mode, true);
46 | break;
47 | case 3:
48 | int color=getColor();
49 | paint.setColor(getEngine().getPreference().getBoolean("nenosync",false)?color:0xffffffff);
50 | paint.setShadowLayer(paint.getStrokeWidth(),0,0,color);
51 | drawGraph(getFft(), canvas, color_mode, false);
52 | paint.setShadowLayer(0, 0, 0, 0);
53 | break;
54 | }
55 | paint.reset();
56 |
57 | }*/
58 | @Override
59 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
60 | {
61 | Paint paint=getPaint();
62 | if ( points == null || points.length != size() )
63 | points = new float[size()];
64 | final float halfWidth=getBorderWidth() / 2;
65 | float x=getStartOffset();
66 | for ( int i=0;i < points.length;i ++ )
67 | {
68 | if(useMode)
69 | checkMode(color_mode,paint);
70 | float height=(float)(buffer[i] / 127d * getBorderHeight());
71 | if ( height < points[i] )
72 | points[i]=Math.max(0,points[i]-(points[i]-height)*getInterpolator((points[i]-height)/points[i]*0.8f)*0.45f);
73 | else if(height>points[i])
74 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height);
75 | height=points[i];
76 | canvas.drawLine(halfWidth, getDrawHeight(), x+=halfWidth, getDrawHeight()-height, paint);
77 | canvas.drawLine(x, getDrawHeight() - height, canvas.getWidth()-halfWidth, getDrawHeight(), paint);
78 | x += halfWidth + getSpaceWidth();
79 |
80 |
81 | }
82 |
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/utils/PreferencesUtils.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.utils;
2 | import android.content.Context;
3 | import android.net.Uri;
4 | import android.database.Cursor;
5 | import java.util.Set;
6 | import java.util.Map;
7 | import java.util.HashMap;
8 | import com.moe.LiveVisualizer.service.SharedPreferences;
9 | import android.os.Handler;
10 | import android.content.ContentResolver;
11 | import android.database.ContentObserver;
12 |
13 | public class PreferencesUtils
14 | {
15 | private ContentObserver observer;
16 | private Context context;
17 | private Map buffer;
18 | public PreferencesUtils(Context context){
19 | this.context=context;
20 | context.getContentResolver().registerContentObserver(Uri.parse(SharedPreferences.URI),true,observer=new ContentObserver(new Handler()){
21 | public void onChange(boolean p1,Uri p2){
22 | buffer.put(p2.getQueryParameter("key"),getString(null,p2));
23 | }
24 | });
25 | buffer=new HashMap<>();
26 | }
27 | public synchronized String getString(String key,String defaultVlue){
28 | String value=buffer.get(key);
29 | if(value!=null)return value;
30 | Cursor cursor=context.getContentResolver().query(getUriBuilder().appendQueryParameter("key",key).build(),null,null,null,null,null);
31 | if(cursor!=null){
32 | if(cursor.moveToFirst())
33 | value=cursor.getString(1);
34 | cursor.close();
35 | }
36 | if(value==null)
37 | value=defaultVlue;
38 | buffer.put(key,value);
39 | return value;
40 | }
41 | public int getInt(String key,int defaultValue){
42 | return Integer.parseInt(getString(key,defaultValue+""));
43 | }
44 | public boolean getBoolean(String key,boolean defaultVlue){
45 | return Boolean.parseBoolean(getString(key,defaultVlue+""));
46 | }
47 | public static String getString(Context context,Uri uri){
48 | if(context!=null){
49 | String value=null;
50 | Cursor cursor=context.getContentResolver().query(uri,null,null,null,null,null);
51 | if(cursor!=null){
52 | if(cursor.moveToFirst())
53 | value=cursor.getString(1);
54 | cursor.close();
55 | }
56 | return value;
57 | }
58 | return uri.getQueryParameter("value");
59 | }
60 | public static int getInt(Context context,Uri uri,int defaultValue){
61 | String value=getString(context,uri);
62 | if(value==null)
63 | return defaultValue;
64 | else
65 | return Integer.parseInt(value);
66 | }
67 | public static boolean getBoolean(Context context,Uri uri,boolean defaultValue){
68 | String value=getString(context,uri);
69 | if(value==null)
70 | return defaultValue;
71 | else
72 | return Boolean.parseBoolean(value);
73 | }
74 | public static Uri.Builder getUriBuilder(){
75 | return new Uri.Builder().scheme("content").authority("moe").path("moe");
76 | }
77 | public void close(){
78 | if(observer!=null)
79 | context.getContentResolver().unregisterContentObserver(observer);
80 | context=null;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/UnKnow1.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Canvas;
5 | import android.graphics.Path;
6 | import android.graphics.PointF;
7 | import android.graphics.Paint;
8 | import java.util.Random;
9 | import com.moe.LiveVisualizer.utils.ColorList;
10 |
11 | public class UnKnow1 extends RingDraw {
12 | private float[] points;
13 | public UnKnow1(ImageDraw draw) {
14 | super(draw);
15 | }
16 | @Override
17 | public void onDraw(Canvas canvas, int color_mode) {
18 | super.onDraw(canvas, color_mode);
19 | drawCircleImage(canvas);
20 | }
21 |
22 | @Override
23 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode) {
24 | PointF center=getPointF();
25 | Paint paint=getPaint();
26 | if (points == null)
27 | points = new float[20];
28 | canvas.save();
29 | int count=-1;
30 | for (int i=0;i < 5;i++) {
31 | if (useMode)
32 | checkMode(color_mode, paint);
33 | //计算高度
34 | for (int n=0;n < 4;n++) {
35 | float height=(float)buffer[++count];
36 | if ( height < points[count] )
37 | points[count]=Math.max(0,points[count]-(points[count]-height)*getInterpolator((points[count]-height)/points[count])*0.8f);
38 | else if(height>points[i])
39 | points[count]=points[count]+(height-points[count])*getInterpolator((height-points[count])/height);
40 | }
41 | canvas.rotate(i * 15, center.x, center.y);
42 | Path path=new Path();
43 | path.moveTo(center.x, center.y - getRadius() - Math.abs((points[i * 4 + 3] - points[i * 4]) / 2));
44 | path.cubicTo(center.x + getRadius() / 2 + points[i * 4], center.y - getRadius() - points[i * 4], center.x + getRadius() + points[i * 4], center.y - getRadius() / 2 - points[i * 4], center.x + getRadius() + Math.abs((points[i * 4] - points[i * 4 + 1]) / 2), center.y);
45 | path.cubicTo(center.x + getRadius() + points[i * 4 + 1], center.y + getRadius() / 2 + points[i * 4 + 1], center.x + getRadius() / 2 + points[i * 4 + 1], center.y + getRadius() + points[i * 4 + 1], center.x, center.y + getRadius() + Math.abs((points[i * 4 + 1] - points[i * 4 + 2]) / 2));
46 | path.cubicTo(center.x - getRadius() / 2 - points[i * 4 + 2], center.y + getRadius() + points[i * 4 + 2], center.x - getRadius() - points[i * 4 + 2], center.y + getRadius() / 2 + points[i * 4 + 2], center.x - getRadius() - Math.abs((points[i * 4 + 2] - points[i * 4 + 3]) / 2), center.y);
47 | path.cubicTo(center.x - getRadius() - points[i * 4 + 3], center.y - getRadius() / 2 - points[i * 4 + 3], center.x - getRadius() / 2 - points[i * 4 + 3], center.y - getRadius() - points[i * 4 + 3], center.x, center.y - getRadius() - Math.abs((points[i * 4 + 3] - points[i * 4]) / 2));
48 | path.addCircle(center.x, center.y, getRadius(), Path.Direction.CCW);
49 | path.close();
50 | canvas.drawPath(path, paint);
51 |
52 | }
53 | canvas.restore();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/line/PopCircleDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.line;
2 | import com.moe.LiveVisualizer.service.LiveWallpaper;
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.util.TypedValue;
6 | import android.graphics.Bitmap;
7 | import android.graphics.PorterDuffXfermode;
8 | import android.graphics.PorterDuff;
9 | import android.graphics.LinearGradient;
10 | import android.view.SurfaceHolder;
11 | import android.graphics.Shader;
12 | import com.moe.LiveVisualizer.internal.ImageDraw;
13 | import com.moe.LiveVisualizer.draw.LineDraw;
14 | import com.moe.LiveVisualizer.utils.ColorList;
15 |
16 | public class PopCircleDraw extends LineDraw
17 | {
18 | private float[] points;
19 | public PopCircleDraw(ImageDraw draw){
20 | super(draw);
21 | }
22 |
23 | /*@Override
24 | public void onDraw(Canvas canvas, int color_mode)
25 | {
26 | Paint paint=getPaint();
27 | switch(color_mode){
28 | case 0:
29 | switch(getEngine().getColorList().size()){
30 | case 0:
31 | paint.setColor(0xff39c5bb);
32 | drawGraph(getFft(),canvas,color_mode,false);
33 | break;
34 | case 1:
35 | paint.setColor(getEngine().getColorList().get(0));
36 | drawGraph(getFft(),canvas,color_mode,false);
37 | break;
38 | default:
39 |
40 | paint.setShader(getShader());
41 | drawGraph(getFft(),canvas,color_mode,false);
42 | paint.setShader(null);
43 | break;
44 | }
45 | break;
46 | case 1:
47 | case 4:
48 | case 2:
49 | drawGraph(getFft(),canvas,color_mode,true);
50 | break;
51 | case 3:
52 | int color=getColor();
53 | paint.setColor(getEngine().getPreference().getBoolean("nenosync",false)?color:0xffffffff);
54 | paint.setShadowLayer(paint.getStrokeWidth(),0,0,color);
55 | drawGraph(getFft(),canvas,color_mode,false);
56 | paint.setShadowLayer(0,0,0,0);
57 | break;
58 | }
59 | paint.reset();
60 |
61 | }
62 | */
63 | @Override
64 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
65 | {
66 | Paint paint=getPaint();
67 | paint.setStrokeWidth(2);
68 | paint.setStyle(Paint.Style.STROKE);
69 | if(points==null||points.length!=size())
70 | points=new float[size()];
71 | float radius=getBorderWidth()/2.0f;
72 | float x=radius;//起始像素
73 | float y=getDrawHeight();
74 | //float y=canvas.getHeight() - engine.getPreference().getInt("height", 10) / 100.0f * canvas.getHeight();
75 | for ( int i=0;i < points.length;i ++ )
76 | {
77 | if(useMode)
78 | checkMode(color_mode,paint);
79 | float height=(float)(buffer[i]/127d*getBorderHeight());
80 | if ( height < points[i] )
81 | points[i]=Math.max(0,points[i]-(points[i]-height)*getInterpolator((points[i]-height)/points[i]*1f)*1f);
82 | else if(height>points[i])
83 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height*0.6f);
84 | height=points[i];
85 | canvas.drawCircle(x,y-height-radius,radius,paint);
86 | x+=getSpaceWidth();
87 | }
88 | }
89 |
90 |
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/duang/Graph.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.duang;
2 | import android.util.DisplayMetrics;
3 | import android.graphics.Canvas;
4 | import java.util.Random;
5 | import android.graphics.Paint;
6 | import android.graphics.Path;
7 | import android.graphics.Matrix;
8 |
9 | public class Graph extends Duang
10 | {
11 | private float rotate,offsetX,offsetY;
12 | private int alpha;
13 | private Paint paint=new Paint();
14 | private Path path=new Path();
15 | private boolean direction;
16 | private Matrix matrix=new Matrix();
17 | private boolean repeat;
18 | public Graph(){
19 | paint.setStrokeWidth(2);
20 | }
21 | @Override
22 | public void draw(Canvas canvas)
23 | {
24 | alpha+=repeat?-4:3;
25 | if(alpha<0||getOffsetX()<-getSize()||getOffsetX()>getMaxWidth()+getSize()||getOffsetY()<-getSize()||getOffsetY()>getMaxHeight()+getSize()){
26 | reset(true);
27 | }
28 | if(alpha>0x8f){
29 | repeat=true;
30 | alpha=0x8f;
31 | }
32 | paint.setAlpha(alpha);
33 | scrollBy(offsetX,offsetY);
34 | path.offset(offsetX,offsetY);
35 | matrix.setRotate(direction?rotate:-rotate,getOffsetX(),getOffsetY());
36 | path.transform(matrix);
37 | //paint.setStyle(Paint.Style.FILL);
38 | canvas.drawPath(path,paint);
39 | //paint.setStyle(Paint.Style.STROKE);
40 | //paint.setShadowLayer(2,0,0,paint.getColor()|0xff000000);
41 | //canvas.drawPath(path,paint);
42 | //paint.setShadowLayer(0,0,0,0);
43 | }
44 |
45 | @Override
46 | public void random(Random random)
47 | {
48 | alpha=0;
49 | repeat=false;
50 | //生成左标
51 | setOffsetX(random.nextInt(getMaxWidth()/3)+getMaxWidth()/3);
52 | setOffsetY(random.nextInt(getMaxWidth()/3)+(getMaxHeight()-getMaxWidth()/3)/2);
53 | //生成图形
54 | path.reset();
55 | switch(GRAPH.$VALUES[random.nextInt(3)]){
56 | case SQUARE:
57 | path.addRect(getOffsetX()-getSize(),getOffsetY()-getSize(),getOffsetX()+getSize(),getOffsetY()+getSize(),Path.Direction.CW);
58 | break;
59 | case TRIANGLE:
60 | double degress=2d/3*Math.PI;
61 | path.moveTo(getOffsetX()+(float)(getSize()*Math.cos(0)),getOffsetY()+(float)(getSize()*Math.sin(0)));
62 | path.lineTo(getOffsetX()+(float)(getSize()*Math.cos(degress)),getOffsetY()+(float)(getSize()*Math.sin(degress)));
63 | path.lineTo(getOffsetX()+(float)(getSize()*Math.cos(degress*2)),getOffsetY()+(float)(getSize()*Math.sin(2*degress)));
64 | path.close();
65 | break;
66 | case ROUND:
67 | path.addCircle(getOffsetX(),getOffsetY(),getSize(),Path.Direction.CW);
68 | break;
69 | }
70 | //随机颜色
71 | paint.setColor(random.nextInt(0xffffff)|0x5f000000);
72 | //
73 | offsetX=(random.nextFloat()*getWind()+1f)*(random.nextBoolean()?2.5f:-2.5f);
74 | offsetY=(random.nextFloat()*getSpeed()+0.01f)*(random.nextBoolean()?0.25f:-0.25f);
75 | direction=random.nextBoolean();
76 | rotate=random.nextFloat()+1f;
77 | //matrix.reset();
78 | //matrix.setTranslate(getOffsetX(),getOffsetY());
79 | }
80 |
81 | enum GRAPH{
82 | SQUARE,ROUND,TRIANGLE;
83 | }
84 |
85 | @Override
86 | public float getSize()
87 | {
88 | return super.getSize()/2;
89 | }
90 | private void scrollBy(float x,float y){
91 | setOffsetX(getOffsetX()+x);
92 | setOffsetY(getOffsetY()+y);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/CircleRadialDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import android.graphics.Paint;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Canvas;
5 | import android.graphics.Bitmap;
6 | import android.graphics.PorterDuffXfermode;
7 | import android.graphics.PorterDuff;
8 | import android.util.TypedValue;
9 | import android.graphics.LinearGradient;
10 | import android.graphics.Shader;
11 | import android.graphics.RadialGradient;
12 | import android.graphics.SweepGradient;
13 | import android.graphics.Point;
14 | import android.graphics.PointF;
15 | import com.moe.LiveVisualizer.internal.ImageDraw;
16 | import com.moe.LiveVisualizer.internal.OnColorSizeChangedListener;
17 | import android.graphics.RectF;
18 | import android.content.SharedPreferences;
19 | import com.moe.LiveVisualizer.utils.ColorList;
20 |
21 | public class CircleRadialDraw extends RingDraw
22 | {
23 | private float[] points;
24 | public CircleRadialDraw(ImageDraw draw)
25 | {
26 | super(draw);
27 | }
28 |
29 | @Override
30 | public void onDraw(Canvas canvas, int color_mode)
31 | {
32 | super.onDraw(canvas,color_mode);
33 | drawCircleImage(canvas);
34 |
35 | }
36 |
37 | @Override
38 | public int size()
39 | {
40 | return super.size()/2;
41 | }
42 |
43 | @Override
44 | public void drawGraph(double[] buffer, Canvas canvas, final int color_mode,boolean useMode)
45 | {
46 | PointF point=getPointF();
47 | float radius=getRadius();
48 | final float radialHeight=getDirection()==OUTSIDE?getBorderHeight():getRadius();
49 | Paint paint=getPaint();
50 | paint.setStrokeWidth(getBorderWidth());
51 | if ( points == null || points.length != size() )
52 | points = new float[size()];
53 | float degress_step=180f / size();
54 | canvas.save();
55 | final PointF center=getPointF();
56 | canvas.rotate(degress_step / 2.0f, center.x, center.y);
57 | int end=size() - 1;
58 | for ( int i=0;i < points.length;i ++ )
59 | {
60 | if(useMode)
61 | checkMode(color_mode,paint);
62 | float height=(float) (buffer[i] / 127d * radialHeight);
63 | if ( height < points[i] )
64 | points[i]=Math.max(0,points[i]-(points[i]-height)*getInterpolator((points[i]-height)/points[i])*0.8f);
65 | else if(height>points[i])
66 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height);
67 | height=points[i];
68 | if(paint.getStrokeCap()==Paint.Cap.ROUND)
69 | canvas.drawLine(point.x,point.y-radius, point.x, point.y -radius+(getDirection()==OUTSIDE?- height:height), paint);
70 | else
71 | canvas.drawRect(point.x-getBorderWidth()/2, point.y-radius, point.x + getBorderWidth()/2, point.y -radius+(getDirection()==OUTSIDE?- height:height), paint);
72 | canvas.rotate(degress_step, center.x, center.y);
73 | //degress+=degress_step;
74 | if ( i == end )
75 | {
76 | if ( degress_step > 0 )
77 | {
78 | canvas.restore();
79 | canvas.save();
80 | degress_step = -degress_step;
81 | canvas.rotate(degress_step / 2.0f, center.x, center.y);
82 | i = -1;
83 | }
84 | else
85 | {
86 | break;
87 | }
88 | }
89 | }
90 | canvas.restore();
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/seekbar_preference.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
22 |
23 |
29 |
30 |
39 |
40 |
49 |
50 |
51 |
52 |
59 |
60 |
61 |
62 |
69 |
70 |
78 |
79 |
88 |
89 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/UnKnow2.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.PointF;
6 | import android.graphics.Path;
7 | import android.graphics.RectF;
8 | import android.graphics.SweepGradient;
9 | import android.graphics.PorterDuffXfermode;
10 | import android.graphics.Bitmap;
11 | import android.graphics.PorterDuff;
12 | import com.moe.LiveVisualizer.service.LiveWallpaper;
13 | import com.moe.LiveVisualizer.utils.ColorList;
14 |
15 | public class UnKnow2 extends RingDraw
16 | {
17 | private float[] points;
18 | private float width;
19 | private float[] lines=new float[4];
20 | private Path path1=new Path(),path2=new Path();
21 |
22 | public UnKnow2(ImageDraw draw){
23 | super(draw);
24 | }
25 | @Override
26 | public void onSizeChanged()
27 | {
28 | // TODO: Implement this method
29 | super.onSizeChanged();
30 | width=(float)(2*getRadius()*Math.PI/(size()-1));
31 |
32 | }
33 |
34 | @Override
35 | public void onDraw(Canvas canvas, int color_mode)
36 | {
37 | drawCircleImage(canvas);
38 | super.onDraw(canvas, color_mode);
39 | }
40 |
41 | @Override
42 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
43 | {
44 | PointF center=getPointF();
45 | Paint paint=getPaint();
46 | paint.setAntiAlias(true);
47 | paint.setStyle(Paint.Style.STROKE);
48 | paint.setStrokeWidth(getBorderWidth());
49 | paint.setStrokeCap(getRound());
50 | if(points==null||points.length!=size())
51 | points=new float[size()];
52 | canvas.save();
53 | canvas.rotate(-90,center.x,center.y);
54 | canvas.translate(center.x,center.y);
55 | double degress=2d/size()*Math.PI;
56 | /*float halfWidth=width/2;
57 | float halfBorder=getBorderWidth()/2f;*/
58 | float radius=getRadius();
59 | for(int i=0;ipoints[i])
64 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height*0.6f);
65 | height=points[i];
66 | double value=degress*i;
67 | if (i==0){
68 | path1.moveTo(lines[0]=(float)((radius-points[i])*Math.cos(value)),lines[1]=(float)((radius-points[i])*Math.sin(value)));
69 | path2.moveTo(lines[2]=(float)((radius+points[i])*Math.cos(value)),lines[3]=(float)((radius+points[i])*Math.sin(value)));
70 |
71 | }else{
72 | path1.lineTo(lines[0]=(float)((radius-points[i])*Math.cos(value)),lines[1]=(float)((radius-points[i])*Math.sin(value)));
73 | path2.lineTo(lines[2]=(float)((radius+points[i])*Math.cos(value)),lines[3]=(float)((radius+points[i])*Math.sin(value)));
74 | }
75 | if(useMode)
76 | checkMode(color_mode,paint);
77 | canvas.drawLines(lines,paint);
78 | //canvas.rotate(degress,center.x,center.y);
79 | }
80 | path1.close();
81 | path2.close();
82 | canvas.drawPath(path1,paint);
83 | canvas.drawPath(path2,paint);
84 | path1.reset();
85 | path2.reset();
86 | canvas.restore();
87 |
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/seekbar_preference_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
22 |
23 |
29 |
30 |
39 |
40 |
49 |
50 |
51 |
52 |
59 |
60 |
61 |
62 |
69 |
70 |
78 |
79 |
88 |
89 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/HeartDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import android.graphics.Canvas;
3 | import com.moe.LiveVisualizer.internal.ImageDraw;
4 | import android.graphics.Path;
5 | import android.graphics.PointF;
6 | import java.util.List;
7 | import java.util.ArrayList;
8 | import android.graphics.Paint;
9 |
10 | public class HeartDraw extends RingDraw
11 | {
12 | private List mPointDatas;
13 | private List mPointControlls;
14 |
15 | public HeartDraw(ImageDraw draw){
16 | super(draw);
17 | }
18 | @Override
19 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode) throws NullPointerException
20 | {
21 | if(mPointControlls==null){
22 | mPointDatas = new ArrayList<>();
23 | mPointControlls = new ArrayList<>();
24 | }else{
25 | mPointDatas.clear();
26 | mPointControlls.clear();
27 | }
28 | PointF center=getPointF();
29 |
30 | float mCenterX = center.x;
31 | float mCenterY = center.y;
32 | float mCircleRadius=getRadius();
33 |
34 |
35 | //初始化数据点数据和辅助点位置
36 | mPointDatas.add(new PointF(mCenterX, mCenterY - mCircleRadius));
37 | mPointDatas.add(new PointF(mCenterX + mCircleRadius, mCenterY));
38 | mPointDatas.add(new PointF(mCenterX, mCenterY + mCircleRadius));
39 | mPointDatas.add(new PointF(mCenterX - mCircleRadius, mCenterY));
40 |
41 | mPointControlls.add(new PointF(mCenterX + mCircleRadius / 2, mCenterY - mCircleRadius));
42 | mPointControlls.add(new PointF(mCenterX + mCircleRadius, mCenterY - mCircleRadius / 2));
43 |
44 | mPointControlls.add(new PointF(mCenterX + mCircleRadius, mCenterY + mCircleRadius / 2));
45 | mPointControlls.add(new PointF(mCenterX + mCircleRadius / 2, mCenterY + mCircleRadius));
46 |
47 | mPointControlls.add(new PointF(mCenterX - mCircleRadius / 2, mCenterY + mCircleRadius));
48 | mPointControlls.add(new PointF(mCenterX - mCircleRadius, mCenterY + mCircleRadius / 2));
49 |
50 | mPointControlls.add(new PointF(mCenterX - mCircleRadius, mCenterY - mCircleRadius / 2));
51 | mPointControlls.add(new PointF(mCenterX - mCircleRadius / 2, mCenterY - mCircleRadius));
52 | mPointDatas.get(0).y +=mCircleRadius/2f;
53 | mPointControlls.get(2).x -= 20.0;
54 |
55 | mPointControlls.get(3).y -= 80.0;
56 | mPointControlls.get(4).y -= 80.0;
57 | mPointControlls.get(5).x += 20.0;
58 | mPointDatas.get(1).x-=10;
59 | mPointDatas.get(3).x+=10;
60 |
61 | Path path = new Path();
62 | path.moveTo(mPointDatas.get(0).x, mPointDatas.get(0).y);
63 | for (int i = 0; i < mPointDatas.size(); i++) {
64 | if (i == mPointDatas.size() - 1) {
65 | path.cubicTo(mPointControlls.get(2 * i).x, mPointControlls.get(2 * i).y, mPointControlls.get(2 * i + 1).x, mPointControlls.get(2 * i + 1).y, mPointDatas.get(0).x, mPointDatas.get(0).y);
66 |
67 | } else {
68 | path.cubicTo(mPointControlls.get(2 * i).x, mPointControlls.get(2 * i).y, mPointControlls.get(2 * i + 1).x, mPointControlls.get(2 * i + 1).y, mPointDatas.get(i + 1).x, mPointDatas.get(i + 1).y);
69 | }
70 |
71 | }
72 | Paint paint=getPaint();
73 | paint.setStyle(Paint.Style.STROKE);
74 | paint.setStrokeWidth(getBorderWidth());
75 | canvas.drawPath(path,paint);
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/fragment/DuangSettingFragment.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.fragment;
2 | import android.os.Bundle;
3 | import android.preference.PreferenceFragment;
4 | import com.moe.LiveVisualizer.R;
5 | import android.preference.ListPreference;
6 | import android.preference.Preference;
7 | import android.content.Intent;
8 | import android.app.Activity;
9 | import java.io.InputStream;
10 | import java.io.FileNotFoundException;
11 | import java.io.OutputStream;
12 | import java.io.FileOutputStream;
13 | import java.io.File;
14 | import java.io.IOException;
15 | import android.os.Handler;
16 | import android.os.Looper;
17 |
18 | public class DuangSettingFragment extends PreferenceFragment implements ListPreference.OnPreferenceChangeListener
19 | {
20 | private ListPreference duang_screen;
21 | @Override
22 | public void onCreate(Bundle savedInstanceState)
23 | {
24 | // TODO: Implement this method
25 | super.onCreate(savedInstanceState);
26 | getPreferenceManager().setSharedPreferencesName("moe");
27 | addPreferencesFromResource(R.xml.duang);
28 | duang_screen=(ListPreference) findPreference("duang_screen");
29 | duang_screen.setOnPreferenceChangeListener(this);
30 | duang_screen.setSummary(duang_screen.getEntries()[duang_screen.findIndexOfValue(getPreferenceManager().getSharedPreferences().getString("duang_screen","0"))]);
31 | }
32 |
33 | @Override
34 | public boolean onPreferenceChange(Preference p1, Object p2)
35 | {
36 | switch(p1.getKey()){
37 | case "duang_screen":
38 | if(p2.equals("4")){
39 | startActivityForResult(new Intent(Intent.ACTION_GET_CONTENT).setType("image/*"),4832);
40 | return false;
41 | }
42 | duang_screen.setSummary(duang_screen.getEntries()[duang_screen.findIndexOfValue(p2.toString())]);
43 | break;
44 | }
45 | return true;
46 | }
47 |
48 | @Override
49 | public void onActivityResult(int requestCode, int resultCode, Intent data)
50 | {
51 | // TODO: Implement this method
52 | super.onActivityResult(requestCode, resultCode, data);
53 | if(requestCode==4832&&resultCode==Activity.RESULT_OK){
54 | save(data);
55 | }
56 | }
57 |
58 |
59 | private void save(final Intent data){
60 | new Thread(){
61 | public void run(){
62 | InputStream is=null;
63 | OutputStream os=null;
64 | try
65 | {
66 | is = getActivity().getContentResolver().openInputStream(data.getData());
67 | os=new FileOutputStream(new File(getActivity().getExternalFilesDir(null),"duang"));
68 | int len=0;
69 | byte[] buffer=new byte[2048];
70 | while((len=is.read(buffer))!=-1)
71 | os.write(buffer,0,len);
72 | os.flush();
73 | new Handler(Looper.getMainLooper()).post(new Runnable(){
74 |
75 | @Override
76 | public void run()
77 | {
78 | duang_screen.setSummary(duang_screen.getEntries()[4]);
79 | getPreferenceManager().getSharedPreferences().edit().putString("duang_screen","4").commit();
80 | }
81 | });
82 | }
83 | catch (Exception e)
84 | {}finally{
85 | try
86 | {
87 | if (os != null)
88 | os.close();
89 | }
90 | catch (IOException e)
91 | {}
92 | try
93 | {
94 | if (is != null)
95 | is.close();
96 | }
97 | catch (IOException e)
98 | {}
99 | }
100 | }
101 | }.start();
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
35 |
36 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
51 |
52 |
53 |
54 |
58 |
59 |
60 |
61 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
100 |
101 |
102 |
103 |
107 |
108 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/CircleTriangleDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Canvas;
5 | import android.graphics.Shader;
6 | import android.graphics.Bitmap;
7 | import android.util.TypedValue;
8 | import android.graphics.Paint;
9 | import android.graphics.SweepGradient;
10 | import android.graphics.PorterDuffXfermode;
11 | import android.graphics.PorterDuff;
12 | import android.graphics.LinearGradient;
13 | import android.graphics.PointF;
14 | import com.moe.LiveVisualizer.utils.ColorList;
15 |
16 | public class CircleTriangleDraw extends RingDraw
17 | {
18 |
19 | private float[] points;
20 | private int size;
21 | private float[] lines=new float[8];
22 | public CircleTriangleDraw(ImageDraw draw)
23 | {
24 | super(draw);
25 | }
26 |
27 | @Override
28 | public int size()
29 | {
30 | // TODO: Implement this method
31 | return size;
32 | }
33 |
34 | @Override
35 | public void onSizeChanged()
36 | {
37 | final double length=Math.min(getEngine().getDisplayWidth(),getEngine().getDisplayHeight()) / 3 * Math.PI;
38 | try
39 | {
40 | size = (int)((length - getSpaceWidth()*2) / (getBorderWidth()*2 + getSpaceWidth()*2));
41 | }
42 | catch (Exception e)
43 | {}
44 | try
45 | {
46 | size = size > getEngine().getFftSize() ?getEngine().getFftSize(): size;
47 | }
48 | catch (Exception e)
49 | {}
50 | }
51 |
52 |
53 | @Override
54 | public void onDraw(Canvas canvas, int color_mode)
55 | {
56 | super.onDraw(canvas,color_mode);
57 | drawCircleImage(canvas);
58 |
59 | }
60 |
61 | @Override
62 | public void drawGraph(double[] buffer, Canvas canvas, final int color_mode,boolean useMode)
63 | {
64 | PointF point=getPointF();
65 | float radius=getRadius();
66 | final float radialHeight=getDirection()==OUTSIDE?getBorderHeight():getRadius();
67 | Paint paint=getPaint();
68 | paint.setStrokeWidth(getBorderWidth());
69 | float width=getBorderWidth()/2;
70 | //paint.setStrokeWidth(0);
71 | if ( points == null || points.length != size() )
72 | points = new float[size()];
73 | float degress_step=360f / size();
74 |
75 | canvas.save();
76 | final PointF center=getPointF();
77 | //canvas.rotate(degress_step / 2.0f, center.x, center.y);
78 | for ( int i=0;i < points.length;i ++ )
79 | {
80 | if(useMode)
81 | checkMode(color_mode,paint);
82 | float height=(float) (buffer[i] / 127d * radialHeight);
83 | if ( height < points[i] )
84 | points[i]=Math.max(0,points[i]-(points[i]-height)*getInterpolator((points[i]-height)/points[i]*0.8f)*0.45f);
85 | else if(height>points[i])
86 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height);
87 | height=points[i];
88 | //if(paint.getStrokeCap()==Paint.Cap.ROUND){
89 | lines[0]=point.x-width-getSpaceWidth()/2;
90 | lines[1]=point.y-radius;
91 | lines[2]=point.x;
92 | lines[3]=point.y-radius+(getDirection()==OUTSIDE?-height:height);
93 | System.arraycopy(lines,2,lines,4,2);
94 | lines[6]=point.x+width+getSpaceWidth()/2;
95 | lines[7]=point.y-radius;
96 | canvas.drawLines(lines, paint);
97 | //canvas.drawArc(point.x-radius,point.y-radius,point.x+radius,point.y+radius,0,360,false,paint);
98 | //}else{
99 | //canvas.drawRect(point.x-paint.getStrokeWidth()/2, point.y-radius, point.x + paint.getStrokeWidth()/2, point.y -radius+(getDirection()==OUTSIDE?- height:height), paint);
100 | //}
101 | canvas.rotate(degress_step, center.x, center.y);
102 | //degress+=degress_step;
103 | }
104 | canvas.restore();
105 | //paint.setStyle(Paint.Style.FILL);
106 | //paint.setStrokeWidth(width*2);
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/duang/Snow.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.duang;
2 | import android.util.DisplayMetrics;
3 | import android.graphics.Canvas;
4 | import java.util.Random;
5 | import android.graphics.Path;
6 | import android.graphics.Paint;
7 | import android.graphics.Matrix;
8 |
9 | public class Snow extends Duang
10 | {
11 | private Path path;
12 | private Paint paint;
13 | private Matrix matrix=new Matrix();
14 | private float windSpeed,speed;
15 | private boolean wind;
16 | public Snow(){
17 | paint=new Paint();
18 | paint.setColor(0xffffffff);
19 | path=new Path();
20 | }
21 |
22 | @Override
23 | public void draw(Canvas canvas)
24 | {
25 | setOffsetY(getOffsetY()+speed);
26 | if(getOffsetX()<-getSize()||getOffsetX()>getMaxWidth()||getOffsetY()>getMaxHeight()){
27 | path.offset(-getOffsetX(),-getOffsetY());
28 | setOffsetY(-getSize());
29 | setOffsetX(getRandom().nextInt(getMaxWidth())-getSize());
30 | path.offset(getOffsetX(),getOffsetY());
31 | }
32 | else if(getOffsetY()>-getSize()){
33 | setOffsetX(getOffsetX()+(wind?windSpeed:-windSpeed));
34 | path.offset(wind?windSpeed:-windSpeed,speed);
35 | canvas.drawPath(path,paint);
36 | }else
37 | path.offset(0,speed);
38 | }
39 |
40 | @Override
41 | public void random(Random random)
42 | {
43 | setOffsetX(random.nextInt((int)(getMaxWidth()-getSize())));
44 | //setSize(random.nextFloat()*(getMaxSize()-getMinSize())+getMinSize());
45 | if(isFirst())
46 | setOffsetY(-random.nextInt(getMaxHeight()));
47 | else
48 | setOffsetY(-getSize());
49 | float scale=getSize()/24;
50 | matrix.setScale(scale,scale);
51 | resetPath();
52 | //随机生成风向
53 | wind=random.nextBoolean();
54 | //根据尺寸计算风力
55 | windSpeed=random.nextFloat()*getWind();
56 | //windSpeed=getSize()/getMaxSize()*getWind();
57 | //根据尺寸计算下降速度
58 | speed=getSize()/getMaxSize()*getSpeed()/10+1;
59 | }
60 | private void resetPath(){
61 | path.reset();
62 | path.moveTo(20.79f,13.95f);
63 | path.lineTo(18.46f,14.57f);
64 | path.lineTo(16.46f,13.44f);
65 | path.lineTo(16.46f,10.56f);//
66 | path.lineTo(18.46f,9.43f);
67 | path.lineTo(20.79f,10.05f);
68 | path.lineTo(21.31f,8.12f);
69 | path.lineTo(19.54f,7.65f);
70 | path.lineTo(20,5.88f);
71 | path.lineTo(18.07f,5.36f);
72 | path.lineTo(17.45f,7.69f);
73 | path.lineTo(15.45f,8.82f);
74 | path.lineTo(13,7.38f);
75 | path.lineTo(13,5.12f);//
76 | path.lineTo(14.71f,3.41f);
77 | path.lineTo(13.29f,2f);
78 | path.lineTo(12,3.29f);
79 | path.lineTo(10.71f,2f);
80 | path.lineTo(9.29f,3.41f);
81 | path.lineTo(11,5.12f);
82 | path.lineTo(11,7.38f);//
83 | path.lineTo(8.5f,8.82f);
84 | path.lineTo(6.5f,7.69f);
85 | path.lineTo(5.92f,5.36f);
86 | path.lineTo(4,5.88f);
87 | path.lineTo(4.47f,7.65f);
88 | path.lineTo(2.7f,8.12f);
89 | path.lineTo(3.22f,10.05f);
90 | path.lineTo(5.55f,9.43f);
91 | path.lineTo(7.55f,10.56f);
92 | path.lineTo(7.55f,13.45f);//
93 | path.lineTo(5.55f,14.58f);
94 | path.lineTo(3.22f,13.96f);
95 | path.lineTo(2.7f,15.89f);
96 | path.lineTo(4.47f,16.36f);
97 | path.lineTo(4,18.12f);
98 | path.lineTo(5.93f,18.64f);
99 | path.lineTo(6.55f,16.31f);
100 | path.lineTo(8.55f,15.18f);
101 | path.lineTo(11,16.62f);
102 | path.lineTo(11,18.88f);//
103 | path.lineTo(9.29f,20.59f);
104 | path.lineTo(10.71f,22f);
105 | path.lineTo(12,20.71f);
106 | path.lineTo(13.29f,22f);
107 | path.lineTo(14.7f,20.59f);
108 | path.lineTo(13,18.88f);
109 | path.lineTo(13,16.62f);//
110 | path.lineTo(15.5f,15.17f);
111 | path.lineTo(17.5f,16.3f);
112 | path.lineTo(18.12f,18.63f);
113 | path.lineTo(20,18.12f);
114 | path.lineTo(19.53f,16.35f);
115 | path.lineTo(21.3f,15.88f);
116 | path.lineTo(20.79f,13.95f);
117 | path.moveTo(9.5f,10.56f);
118 | path.lineTo(12,9.11f);
119 | path.lineTo(14.5f,10.56f);
120 | path.lineTo(14.5f,13.44f);//
121 | path.lineTo(12,14.89f);
122 | path.lineTo(9.5f,13.44f);
123 | path.lineTo(9.5f,10.56f);//
124 | path.close();
125 | path.transform(matrix);
126 | path.offset(getOffsetX(),getOffsetY());
127 | }
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
15 |
18 |
21 |
22 |
28 |
34 |
40 |
47 |
52 |
57 |
62 |
68 |
73 |
80 |
84 |
89 |
94 |
99 |
103 |
109 |
115 |
118 |
121 |
124 |
127 |
130 |
131 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/CenterRadialDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Canvas;
5 | import com.moe.LiveVisualizer.internal.OnColorSizeChangedListener;
6 | import android.graphics.Shader;
7 | import android.graphics.Bitmap;
8 | import android.graphics.PointF;
9 | import android.graphics.Paint;
10 | import android.graphics.SweepGradient;
11 | import android.graphics.PorterDuffXfermode;
12 | import android.graphics.LinearGradient;
13 | import android.graphics.PorterDuff;
14 | import android.util.TypedValue;
15 | import com.moe.LiveVisualizer.draw.CircleDraw;
16 | import com.moe.LiveVisualizer.utils.ColorList;
17 |
18 | public class CenterRadialDraw extends RingDraw
19 | {
20 |
21 | private float[] points;
22 | public CenterRadialDraw(ImageDraw draw){
23 | super(draw);
24 | }
25 | /*@Override
26 | public void onDraw(Canvas canvas, int color_mode)
27 | {
28 | Paint paint=getP;
29 | paint.setStrokeCap(getRound());
30 | paint.setStrokeWidth(borderWidth);
31 | switch(color_mode){
32 | case 0:
33 | switch ( getEngine().getColorList().size() )
34 | {
35 | case 0:
36 | paint.setColor(0xff39c5bb);
37 | drawGraph(getFft(), canvas,color_mode,false);
38 | break;
39 | case 1:
40 | paint.setColor(getEngine().getColorList().get(0));
41 | drawGraph(getFft(), canvas,color_mode,false);
42 | break;
43 | default:
44 | final int layer=canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),null,Canvas.ALL_SAVE_FLAG);
45 | drawGraph(getFft(),canvas,color_mode,false);
46 | if ( shader == null )
47 | shader = new SweepGradient(canvas.getWidth() / 2.0f, canvas.getHeight() / 2.0f, getEngine().getColorList().toArray(), null);
48 | if(shaderBuffer==null){
49 | shaderBuffer=Bitmap.createBitmap(canvas.getWidth(),canvas.getHeight(),Bitmap.Config.ARGB_4444);
50 | Canvas shaderCanvas=new Canvas(shaderBuffer);
51 | paint.setShader(shader);
52 | shaderCanvas.drawRect(0,0,shaderCanvas.getWidth(),shaderCanvas.getHeight(),paint);
53 | paint.setShader(null);
54 | }
55 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
56 | //canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
57 | canvas.drawBitmap(shaderBuffer, 0, 0, paint);
58 | //paint.setShader(null);
59 | paint.setXfermode(null);
60 | canvas.restoreToCount(layer);
61 | //canvas.drawBitmap(src, 0, 0, paint);
62 | //src.recycle();
63 | /*if ( shader == null )
64 | shader = new SweepGradient(canvas.getWidth() / 2.0f, canvas.getHeight() / 2.0f, getEngine().getColorList().toArray(), null);
65 | paint.setShader(shader);
66 | drawLines(getFft(), canvas, false,color_mode);
67 | paint.setShader(null);*/
68 | /*break;
69 | }
70 | break;
71 | case 1:
72 | case 2:
73 | case 4:
74 | drawGraph(getFft(),canvas,color_mode,true);
75 | break;
76 | case 3:
77 | int color=getColor();
78 | paint.setColor(getEngine().getPreference().getBoolean("nenosync",false)?color:0xffffffff);
79 | paint.setShadowLayer(borderWidth,0,0,color);
80 | drawGraph(getFft(),canvas,color_mode,false);
81 | paint.setShadowLayer(0,0,0,0);
82 | break;
83 | }
84 | paint.reset();
85 | }*/
86 |
87 |
88 | @Override
89 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
90 | {
91 | if(points==null||points.length!=size())
92 | points=new float[size()];
93 | Paint paint=getPaint();
94 | paint.setStrokeWidth(getBorderWidth());
95 | canvas.save();
96 | PointF point=getPointF();
97 | canvas.rotate(-90,point.x,point.y);
98 | float degress=360f/points.length;
99 | for(int i=0;i100?0:100-distance);
97 | }
98 | }catch(Exception e){
99 | if(mVisualizer!=null){
100 | if(mVisualizer.getEnabled())
101 | mVisualizer.setEnabled(false);
102 | mVisualizer.release();
103 | }
104 | initVisualizer();
105 | }
106 | }
107 | break;
108 | }
109 | return true;
110 | }
111 | private void fill(double[] b) {
112 | for (int i=0;i < b.length;i++)
113 | b[i] = 0;
114 | }
115 | private double a(double data1, double data2) {
116 | double d=Math.hypot(data1, data2);
117 | d = Math.min(127,d>64?d*0.7d:d*1.3d);
118 | return d;
119 | }
120 | /*private double[] fft(byte[] wave) {
121 | wave[0]=0;
122 | wave[1]=0;
123 | for (int i = 0,j=0; i=Build.VERSION_CODES.LOLLIPOP?R.layout.seekbar_preference_material:R.layout.seekbar_preference,parent,false);
34 | return view;
35 | }
36 |
37 | @Override
38 | protected void onBindView(View view)
39 | {
40 | super.onBindView(view);
41 | final SeekBar seekbar=(SeekBar)view.findViewById(R.id.seekbar);
42 | seekbar.setOnSeekBarChangeListener(this);
43 | TextView tips=(TextView)view.findViewById(R.id.tips);
44 | seekbar.setTag(tips);
45 | ((View)view.findViewById(R.id.plus)).setOnClickListener(new View.OnClickListener(){
46 |
47 | @Override
48 | public void onClick(View p1)
49 | {
50 | seekbar.setProgress(seekbar.getProgress()+1);
51 | onStopTrackingTouch(seekbar);
52 | }
53 | });
54 | ((View)view.findViewById(R.id.minus)).setOnClickListener(new View.OnClickListener(){
55 |
56 | @Override
57 | public void onClick(View p1)
58 | {
59 | seekbar.setProgress(seekbar.getProgress()-1);
60 | onStopTrackingTouch(seekbar);
61 | }
62 | });
63 | seekbar.setMax(max);
64 | seekbar.setProgress(progress);
65 | tips.setText(seekbar.getProgress()+(unit!=null?unit.toString():""));
66 | }
67 | public void setMax(int max){
68 | this.max=max;
69 | notifyChanged();
70 | }
71 | @Override
72 | public void onProgressChanged(SeekBar p1, int p2, boolean p3)
73 | {
74 | if(p1.getTag()!=null)
75 | ((TextView)p1.getTag()).setText(p2+(unit!=null?unit.toString():""));
76 | }
77 |
78 | @Override
79 | public void onStartTrackingTouch(SeekBar p1)
80 | {
81 | // TODO: Implement this method
82 | }
83 | public void setUnit(CharSequence unit){
84 | this.unit=unit;
85 | notifyChanged();
86 | }
87 |
88 | @Override
89 | public void onStopTrackingTouch(SeekBar p1)
90 | {
91 | if(callChangeListener(p1.getProgress())){
92 | if(shouldPersist()){
93 | progress=p1.getProgress();
94 | persistInt(p1.getProgress());
95 | }
96 | }
97 | }
98 |
99 | @Override
100 | protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue)
101 | {
102 | init=true;
103 | if(restorePersistedValue){
104 | progress=getPersistedInt(defaultValue!=null?defaultValue:progress);
105 | }
106 | }
107 |
108 | @Override
109 | protected Object onGetDefaultValue(TypedArray a, int index)
110 | {
111 | progress=a.getInt(index,progress);
112 | return progress;
113 | }
114 |
115 | @Override
116 | public void setDefaultValue(Object defaultValue)
117 | {
118 | if(!init)
119 | progress=defaultValue==null?progress:(int)defaultValue;
120 | }
121 |
122 | @Override
123 | protected Parcelable onSaveInstanceState()
124 | {
125 | return new SavedState(super.onSaveInstanceState());
126 | }
127 |
128 | @Override
129 | protected void onRestoreInstanceState(Parcelable state)
130 | {
131 | SavedState save=(SeekBarPreference.SavedState) state;
132 | super.onRestoreInstanceState(save.getSuperState());
133 | max=save.max;
134 | progress=save.progress;
135 | unit=save.unit;
136 |
137 | }
138 |
139 | class SavedState extends BaseSavedState{
140 | int max,progress;
141 | CharSequence unit;
142 | public SavedState(Parcelable parcel){
143 | super(parcel);
144 | }
145 | public SavedState(Parcel parcel){
146 | super(parcel);
147 | max=parcel.readInt();
148 | progress=parcel.readInt();
149 | unit=(CharSequence)parcel.readValue(CharSequence.class.getClassLoader());
150 | }
151 | @Override
152 | public void writeToParcel(Parcel dest, int flags)
153 | {
154 | // TODO: Implement this method
155 | super.writeToParcel(dest, flags);
156 | dest.writeInt(SeekBarPreference.this.max);
157 | dest.writeInt(SeekBarPreference.this.progress);
158 | dest.writeValue(SeekBarPreference.this.unit);
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/line/LineChartDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.line;
2 | import android.graphics.Paint;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Canvas;
5 | import android.graphics.Rect;
6 | import android.graphics.Bitmap;
7 | import android.graphics.PorterDuffXfermode;
8 | import android.graphics.PorterDuff;
9 | import android.graphics.LinearGradient;
10 | import android.util.TypedValue;
11 | import android.graphics.Shader;
12 | import com.moe.LiveVisualizer.internal.ImageDraw;
13 | import com.moe.LiveVisualizer.draw.LineDraw;
14 | import com.moe.LiveVisualizer.utils.ColorList;
15 | import android.graphics.RectF;
16 | import android.graphics.Path;
17 |
18 | public class LineChartDraw extends LineDraw
19 | {
20 | private float[] tmpData=new float[8];
21 | private float[] pointX;
22 | private float[] points;
23 | public LineChartDraw(ImageDraw draw)
24 | {
25 | super(draw);
26 | }
27 |
28 | @Override
29 | public void notifySizeChanged() {
30 | super.notifySizeChanged();
31 | if(pointX==null||pointX.length!=size()){
32 | pointX=new float[size()];
33 | float offsetX=getStartOffset();
34 | for(int i=0;ipoints[i])
117 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height*0.6f);
118 | }
119 | Path path = new Path();
120 | path.moveTo(offsetX,getDrawHeight());
121 | for (int i = 0; i < size(); i ++) {
122 | float startX=pointX[i];
123 | float startY=points[i];
124 | float endX,endY;
125 | if(i+1==size()){
126 | endX=canvas.getWidth();
127 | endY=getDrawHeight();
128 | }else{
129 | endX=pointX[i+1];
130 | endY=points[i+1];
131 | }
132 | float centerX=startX+(endX-startX)/2;
133 | float centerY=startY+(endY-startY)/2;
134 | path.quadTo(startX,startY,centerX,centerY);
135 | }
136 | path.lineTo(canvas.getWidth(),getDrawHeight());
137 | if (useMode)
138 | checkMode(color_mode, paint);
139 |
140 | canvas.drawPath(path, paint);
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/RippleDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import android.graphics.Shader;
3 | import android.graphics.Bitmap;
4 | import android.graphics.PointF;
5 | import com.moe.LiveVisualizer.internal.ImageDraw;
6 | import com.moe.LiveVisualizer.service.LiveWallpaper;
7 | import android.util.TypedValue;
8 | import com.moe.LiveVisualizer.internal.OnColorSizeChangedListener;
9 | import android.graphics.Canvas;
10 | import android.graphics.Paint;
11 | import android.graphics.SweepGradient;
12 | import android.graphics.PorterDuffXfermode;
13 | import android.graphics.PorterDuff;
14 | import android.graphics.LinearGradient;
15 | import com.moe.LiveVisualizer.draw.CircleDraw;
16 | import com.moe.LiveVisualizer.utils.ColorList;
17 |
18 | public class RippleDraw extends RingDraw
19 | {
20 | private float[] points;
21 | //private float borderHeight,borderWidth;
22 |
23 | public RippleDraw(ImageDraw draw){
24 | super(draw);
25 | }
26 |
27 | /*@Override
28 | public void onDraw(Canvas canvas, int color_mode)
29 | {
30 | Paint paint=getPaint()
31 | paint.setStrokeCap(getRound());
32 | paint.setStrokeWidth(borderWidth);
33 | switch(color_mode){
34 | case 0:
35 | switch ( getEngine().getColorList().size() )
36 | {
37 | case 0:
38 | paint.setColor(0xff39c5bb);
39 | drawGraph(getFft(),canvas,color_mode,false);
40 | break;
41 | case 1:
42 | paint.setColor(getEngine().getColorList().get(0));
43 | drawGraph(getFft(), canvas,color_mode,false);
44 | break;
45 | default:
46 | final int layer=canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),null,Canvas.ALL_SAVE_FLAG);
47 | drawGraph(getFft(),canvas,color_mode,false);
48 | paint.setStyle(Paint.Style.FILL);
49 | if ( shader == null )
50 | shader = new SweepGradient(canvas.getWidth() / 2.0f, canvas.getHeight() / 2.0f, getEngine().getColorList().toArray(), null);
51 | if(shaderBuffer==null){
52 | shaderBuffer=Bitmap.createBitmap(canvas.getWidth(),canvas.getHeight(),Bitmap.Config.ARGB_4444);
53 | Canvas shaderCanvas=new Canvas(shaderBuffer);
54 | paint.setShader(shader);
55 | shaderCanvas.drawRect(0,0,shaderCanvas.getWidth(),shaderCanvas.getHeight(),paint);
56 | paint.setShader(null);
57 | }
58 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
59 | //canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
60 | canvas.drawBitmap(shaderBuffer, 0, 0, paint);
61 | //paint.setShader(null);
62 | paint.setXfermode(null);
63 | canvas.restoreToCount(layer);
64 | //canvas.drawBitmap(src, 0, 0, paint);
65 | //src.recycle();
66 | /*if ( shader == null )
67 | shader = new SweepGradient(canvas.getWidth() / 2.0f, canvas.getHeight() / 2.0f, getEngine().getColorList().toArray(), null);
68 | paint.setShader(shader);
69 | drawLines(getFft(), canvas, false,color_mode);
70 | paint.setShader(null);*/
71 | /*break;
72 | }
73 | break;
74 | case 1:
75 | case 4:
76 | case 2:
77 | drawGraph(getFft(),canvas,color_mode,true);
78 | break;
79 | case 3:
80 | int color=getColor();
81 | paint.setColor(getEngine().getPreference().getBoolean("nenosync",false)?color:0xffffffff);
82 | paint.setShadowLayer(paint.getStrokeWidth(),0,0,color);
83 | drawGraph(getFft(),canvas,color_mode,false);
84 | paint.setShadowLayer(0,0,0,0);
85 | break;
86 | }
87 | paint.reset();
88 | }*/
89 |
90 | /*@Override
91 | public void onBorderWidthChanged(int width)
92 | {
93 | borderWidth=width;
94 | paint.setStrokeWidth(width);
95 | }
96 |
97 | @Override
98 | public void onBorderHeightChanged(int height)
99 | {
100 | borderHeight=height;
101 | }
102 |
103 | @Override
104 | public void onSpaceWidthChanged(int space)
105 | {
106 |
107 | }
108 | */
109 | @Override
110 | public int size()
111 | {
112 | return 16;
113 | }
114 |
115 | @Override
116 | public void drawGraph(double[] buffer, Canvas canvas, int color_mode, boolean useMode)
117 | {
118 | if(points==null||points.length!=size())
119 | points=new float[size()];
120 | Paint paint=getPaint();
121 | paint.setStyle(Paint.Style.STROKE);
122 | paint.setStrokeWidth(getBorderWidth());
123 | PointF point=getPointF();
124 | for(int i=0;ipoints[i])
131 | points[i]=points[i]+(height-points[i])*getInterpolator((height-points[i])/height);
132 | height=points[i];
133 | //if(paint.getStrokeCap()==Paint.Cap.ROUND)
134 | canvas.drawCircle(point.x,point.y,height,paint);
135 | //else
136 | // canvas.drawRect(point.x-paint.getStrokeWidth()/2,point.y-height,point.x+paint.getStrokeWidth()/2,point.y,paint);
137 | //canvas.rotate(degress,point.x,point.y)
138 | }
139 |
140 | //paint.setStyle(Paint.Style.FILL);
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/activity/CropActivity.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.activity;
2 | import android.app.Activity;
3 | import android.os.Bundle;
4 | import com.moe.LiveVisualizer.widget.CropView;
5 | import android.content.Intent;
6 | import android.net.Uri;
7 | import android.graphics.BitmapFactory;
8 | import java.io.FileNotFoundException;
9 | import android.widget.Toast;
10 | import android.view.Menu;
11 | import android.view.MenuItem;
12 | import android.graphics.Bitmap;
13 | import android.os.Build;
14 | import android.Manifest;
15 | import android.content.pm.PackageManager;
16 | import java.io.OutputStream;
17 | import java.io.IOException;
18 | import android.graphics.Matrix;
19 |
20 | public class CropActivity extends Activity implements CropView.CropCallback
21 | {
22 | private CropView crop;
23 | private MenuItem cropItem;
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState)
26 | {
27 | super.onCreate(savedInstanceState);
28 | setTitle("裁剪图片");
29 | crop=new CropView(this);
30 | setContentView(crop);
31 | /*
32 | intent.putExtra("aspectX", display.getWidth());
33 | intent.putExtra("aspectY", display.getHeight());
34 | intent.putExtra("outputX",display.getWidth());
35 | intent.putExtra("outputY",display.getHeight());
36 | intent.putExtra("output", Uri.fromFile(wallpaper));
37 | intent.putExtra("return-data",false);
38 | intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());*/
39 | Intent intent=getIntent();
40 | Uri uri=intent.getData();
41 | try
42 | {
43 | crop.setImage(BitmapFactory.decodeStream(getContentResolver().openInputStream(uri)));
44 | }
45 | catch (Exception e)
46 | {
47 | Toast.makeText(getApplicationContext(),"无法读取文件",Toast.LENGTH_SHORT).show();
48 | finish();
49 | return;
50 | }
51 | crop.setCrop(intent.getIntExtra("aspectX",0),intent.getIntExtra("aspectY",0),intent.getBooleanExtra("two",false));
52 | if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M&&checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED)
53 | requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},342);
54 | }
55 |
56 | @Override
57 | public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
58 | {
59 | // TODO: Implement this method
60 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
61 | if(requestCode==342){
62 | if(grantResults[0]!=PackageManager.PERMISSION_GRANTED)
63 | finish();
64 | }
65 | }
66 |
67 | @Override
68 | public boolean onCreateOptionsMenu(Menu menu)
69 | {
70 | cropItem=menu.add(0,0,0,"裁剪");
71 | cropItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
72 | return true;
73 | }
74 |
75 | @Override
76 | public boolean onOptionsItemSelected(MenuItem item)
77 | {
78 | switch(item.getItemId()){
79 | case android.R.id.home:
80 | finish();
81 | break;
82 | case 0:
83 | if(item.getTitle().length()>2)
84 | break;
85 | item.setTitle("正在裁剪");
86 | crop.crop(this);
87 | break;
88 | }
89 | return true;
90 | }
91 |
92 | @Override
93 | public void success(Bitmap b1, Bitmap b2)
94 | {
95 | if(b1!=null||b2!=null)
96 | if(getIntent().getBooleanExtra("return-data",false)){
97 | Intent intent=new Intent();
98 | intent.putExtra(Intent.EXTRA_STREAM,b1);
99 | setResult(RESULT_OK,intent);
100 | finish();
101 | return;
102 | }
103 | int outputX=getIntent().getIntExtra("outputX",-1);
104 | int outputY=getIntent().getIntExtra("outputY",-1);
105 | b1=scale(b1,outputX,outputY);
106 | if( b1!=null&&getIntent().getParcelableExtra("output")!=null){
107 | OutputStream os=null;
108 | try
109 | {
110 | os=getContentResolver().openOutputStream((Uri)getIntent().getParcelableExtra("output"));
111 |
112 | b1.compress(Bitmap.CompressFormat.valueOf((getIntent().getStringExtra("outputFormat")==null?Bitmap.CompressFormat.PNG.toString():getIntent().getStringExtra("outputFormat"))),100,os);
113 | os.flush();
114 | }
115 | catch (Exception e)
116 | {}finally{
117 | try
118 | {
119 | if ( os != null )os.close();
120 | }
121 | catch (IOException e)
122 | {}
123 | }
124 | }
125 | b2=scale(b2,outputY,outputX);
126 | if( b2!=null&&getIntent().getParcelableExtra("output2")!=null){
127 | OutputStream os=null;
128 | try
129 | {
130 | os=getContentResolver().openOutputStream((Uri)getIntent().getParcelableExtra("output2"));
131 |
132 | b2.compress(Bitmap.CompressFormat.valueOf((getIntent().getStringExtra("outputFormat")==null?Bitmap.CompressFormat.PNG.toString():getIntent().getStringExtra("outputFormat"))),100,os);
133 | os.flush();
134 | }
135 | catch (Exception e)
136 | {}finally{
137 | try
138 | {
139 | if ( os != null )os.close();
140 | }
141 | catch (IOException e)
142 | {}
143 | }
144 | }
145 | setResult(RESULT_OK);
146 | finish();
147 | }
148 |
149 | private Bitmap scale(Bitmap src,float width,float height){
150 | if(src==null)return null;
151 | if(width<1||height<1)return src;
152 | float scaleX=width/src.getWidth();
153 | float scaleY=height/src.getHeight();
154 | Bitmap bit=Bitmap.createScaledBitmap(src,(int)(src.getWidth()*scaleX),(int)(src.getHeight()*scaleY),true);
155 | if(bit!=src)
156 | src.recycle();
157 | return bit;
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/duang/Engine.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.duang;
2 | import com.moe.LiveVisualizer.service.LiveWallpaper;
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import android.util.DisplayMetrics;
6 | import android.view.WindowManager;
7 | import android.app.Service;
8 | import android.graphics.Canvas;
9 | import java.util.Iterator;
10 | import java.lang.reflect.Constructor;
11 | import java.lang.reflect.InvocationTargetException;
12 | import android.content.Context;
13 | import android.graphics.Bitmap;
14 | import android.graphics.BitmapFactory;
15 | import java.io.File;
16 |
17 | public class Engine
18 | {
19 | private Class duang;
20 | private int wind,speed,maxSize,minSize;
21 | private List list;
22 | private LiveWallpaper.WallpaperEngine engine;
23 | private DisplayMetrics display=new DisplayMetrics();
24 | private Bitmap buffer;
25 | private Engine(LiveWallpaper.WallpaperEngine engine){
26 | this.engine=engine;
27 | wind=engine.getPreference().getInt("duang_wind",2);
28 | speed=engine.getPreference().getInt("duang_speed",30);
29 | maxSize=engine.getPreference().getInt("duang_maxSize",50);
30 | minSize=engine.getPreference().getInt("duang_minSize",10);
31 | changed();
32 | list=new ArrayList<>();
33 | setDuang(Integer.parseInt(engine.getPreference().getString("duang_screen","0")));
34 |
35 | }
36 |
37 | public int getSpeed()
38 | {
39 | // TODO: Implement this method
40 | return speed;
41 | }
42 |
43 | public DisplayMetrics getDisplay()
44 | {
45 | // TODO: Implement this method
46 | return display;
47 | }
48 |
49 | public int getWind()
50 | {
51 | // TODO: Implement this method
52 | return wind;
53 | }
54 |
55 | public int getMxSize()
56 | {
57 | // TODO: Implement this method
58 | return maxSize;
59 | }
60 |
61 | public int getMinSize()
62 | {
63 | // TODO: Implement this method
64 | return minSize;
65 | }
66 |
67 |
68 | public Bitmap getBuffer()
69 | {
70 | return buffer;
71 | }
72 | public Context getContext(){
73 | return engine.getContext();
74 | }
75 | public static Engine init(LiveWallpaper.WallpaperEngine engine){
76 | return new Engine(engine);
77 | }
78 | public void draw(Canvas canvas){
79 | synchronized(list){
80 | Iterator iterator=list.iterator();
81 | while(iterator.hasNext())
82 | iterator.next().draw(canvas);
83 | }
84 | }
85 | public void reset(){
86 | Iterator iterator=list.iterator();
87 | while(iterator.hasNext())
88 | iterator.next().reset(false);
89 | }
90 | public void changed(){
91 | ((WindowManager)engine.getContext().getSystemService(Service.WINDOW_SERVICE)).getDefaultDisplay().getRealMetrics(display);
92 | }
93 | public void setSizeChanged(int size){
94 | synchronized(list){
95 | if(size>list.size()){
96 | for(int i=list.size();i iterator=list.iterator();
186 | while(iterator.hasNext())
187 | iterator.next().reset(true);
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/LineDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Paint;
5 | import android.graphics.Canvas;
6 | import android.graphics.PorterDuffXfermode;
7 | import android.graphics.PorterDuff;
8 |
9 | public abstract class LineDraw extends Draw {
10 | private int size;
11 | private float spaceWidth,borderHeight,borderWidth,drawHeight,sourceSpace,offsetX;
12 | private Paint paint;
13 | private boolean antialias;
14 | public LineDraw(ImageDraw draw) {
15 | super(draw);
16 | LiveWallpaper.WallpaperEngine engine=getEngine();
17 | paint = new Paint();
18 | //paint.setStyle(Paint.Style.FILL);
19 | //paint.setStrokeCap(getEngine().getPreference().getBoolean("round", true) ?Paint.Cap.ROUND: Paint.Cap.SQUARE);
20 | borderHeight = engine.getPreference().getInt("borderHeight", 100);
21 | sourceSpace = engine.getPreference().getInt("spaceWidth", 20);
22 | drawHeight = engine.getDisplayHeight() - engine.getPreference().getInt("height", 10) / 100.0f * engine.getDisplayHeight();
23 | borderWidth = engine.getPreference().getInt("borderWidth", 30);
24 | size = engine.getPreference().getInt("num", 50);
25 | paint.setStrokeWidth(borderWidth);
26 | notifySizeChanged();
27 | }
28 |
29 | @Override
30 | public void setAntialias(boolean antialias) {
31 | this.antialias = antialias;
32 | //paint.setAntiAlias(antialias);
33 | }
34 | @Override
35 | public void setNum(int num) {
36 | this.size = num;
37 | notifySizeChanged();
38 | }
39 |
40 | public Paint getPaint() {
41 | return paint;
42 | }
43 | public float getDrawHeight() {
44 | return drawHeight;
45 | }
46 | public float getSpaceWidth() {
47 | return spaceWidth;
48 | }
49 | public float getBorderWidth() {
50 | return borderWidth;
51 | }
52 | public float getBorderHeight() {
53 | return borderHeight;
54 | }
55 | @Override
56 | final public void onDrawHeightChanged(float height) {
57 | this.drawHeight = height;
58 | }
59 |
60 | @Override
61 | final public void onBorderHeightChanged(int height) {
62 | this.borderHeight = height;
63 | notifySizeChanged();
64 | }
65 |
66 | @Override
67 | public void draw(Canvas canvas) {
68 | paint.setStrokeWidth(borderWidth);
69 | paint.setStrokeCap(getRound());
70 | paint.setStyle(Paint.Style.FILL);
71 | super.draw(canvas);
72 | }
73 |
74 | @Override
75 | public void onDraw(Canvas canvas, int color_mode) {
76 | if (isFinalized())return;
77 | Paint paint=getPaint();
78 | paint.setStrokeCap(getRound());
79 | paint.setAntiAlias(antialias);
80 | paint.setDither(antialias);
81 | switch (color_mode) {
82 | case 0:
83 | switch (getEngine().getColorList().size()) {
84 | case 0:
85 | paint.setColor(0xff39c5bb);
86 | drawGraph(getFft(), canvas, color_mode, false);
87 | break;
88 | case 1:
89 | paint.setColor(getEngine().getColorList().get(0));
90 | drawGraph(getFft(), canvas, color_mode, false);
91 | break;
92 | default:
93 | paint.setShader(getShader());
94 | drawGraph(getFft(), canvas, color_mode, false);
95 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
96 | paint.setShader(null);
97 | break;
98 | }
99 | break;
100 | case 1:
101 | case 2:
102 | if (getEngine() != null)
103 | switch (getEngine().getColorList().size()) {
104 | case 0:
105 | paint.setColor(0xff39c5bb);
106 | break;
107 | default:
108 | paint.setColor(getEngine().getColorList().get(0));
109 | break;
110 | }
111 | case 4:
112 | drawGraph(getFft(), canvas, color_mode, true);
113 | break;
114 | case 3:
115 | int color=getColor();
116 | try {
117 | paint.setColor(getEngine().getPreference().getBoolean("nenosync", false) ?color: 0xffffffff);
118 | } catch (NullPointerException e) {}
119 | paint.setShadowLayer(getBorderWidth(), 0, 0, color);
120 | drawGraph(getFft(), canvas, color_mode, false);
121 | paint.clearShadowLayer();
122 | break;
123 | }
124 | paint.reset();
125 | }
126 |
127 |
128 |
129 |
130 |
131 | @Override
132 | final public void onBorderWidthChanged(int width) {
133 | this.borderWidth = width;
134 | paint.setStrokeWidth(width);
135 | notifySizeChanged();
136 | }
137 |
138 | @Override
139 | final public void onSpaceWidthChanged(int space) {
140 | sourceSpace = space;
141 | notifySizeChanged();
142 | }
143 | @Override
144 | public int size() {
145 | return size;
146 | }
147 |
148 | @Override
149 | public void notifySizeChanged() {
150 | /*try
151 | {
152 | size = (int)(getEngine().getDisplayWidth()/sourceSpace);
153 | }
154 | catch (Exception e)
155 | {}
156 | try
157 | {
158 | size = size > getEngine().getFftSize() ?getEngine().getFftSize(): size;
159 | spaceWidth = (float)getEngine().getDisplayWidth()/(size-1);
160 |
161 | }
162 | catch (Exception e)
163 | {}*/
164 | spaceWidth=getEngine().getDisplayWidth()/(float)size;
165 | offsetX=(getSpaceWidth()-getBorderWidth())/2f;
166 | }
167 |
168 | @Override
169 | public void finalized() {
170 | // TODO: Implement this method
171 | super.finalized();
172 | paint.reset();
173 | }
174 | public float getStartOffset(){
175 | return offsetX;
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/Draw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Canvas;
5 | import android.graphics.Shader;
6 | import com.moe.LiveVisualizer.service.LiveWallpaper.WallpaperEngine;
7 | import android.graphics.Color;
8 | import android.animation.ValueAnimator;
9 | import android.animation.ObjectAnimator;
10 | import android.os.Handler;
11 | import android.os.Looper;
12 | import android.os.Message;
13 | import android.animation.TypeEvaluator;
14 | import android.animation.PropertyValuesHolder;
15 | import android.graphics.Matrix;
16 | import android.graphics.Paint;
17 | import android.animation.ArgbEvaluator;
18 | import com.moe.LiveVisualizer.utils.ColorList;
19 |
20 | abstract class Draw implements com.moe.LiveVisualizer.inter.Draw {
21 | private boolean round,finalize;
22 | private int[] fade=new int[2];
23 | private Handler handler;
24 | private int index,color_step;
25 | private ImageDraw draw;
26 | private ValueAnimator anime;
27 | private LiveWallpaper.WallpaperEngine engine;
28 | private boolean isInterval;
29 | private ArgbEvaluator argb;
30 | Draw(ImageDraw draw) {
31 |
32 | this.draw = draw;
33 | this.engine = draw.getEngine();
34 | round = engine.getPreference().getBoolean("round", false);
35 |
36 | }
37 |
38 | @Override
39 | final public void setRound(boolean round) {
40 | this.round = round;
41 | }
42 |
43 | public Paint.Cap getRound() {
44 | return round ?Paint.Cap.ROUND: Paint.Cap.SQUARE;
45 | }
46 | @Override
47 | public LiveWallpaper.WallpaperEngine getEngine() {
48 | return engine;
49 | }
50 |
51 | @Override
52 | public double[] getFft() {
53 | return draw.getFft();
54 | }
55 |
56 | @Override
57 | public byte[] getWave() {
58 | return draw.getWave();
59 | }
60 |
61 | @Override
62 | public Shader getShader() {
63 | return draw.getShader();
64 | }
65 |
66 | @Override
67 | public int getColor() {
68 | if (handler == null) {
69 | handler = new Handler(Looper.getMainLooper(), new Handler.Callback(){
70 |
71 | @Override
72 | public boolean handleMessage(Message p1) {
73 | anime.start();
74 | return false;
75 | }
76 | });
77 | argb = new ArgbEvaluator();
78 | anime = new ValueAnimator();
79 | anime.setRepeatCount(0);
80 | anime.setIntValues(0);
81 | anime.setRepeatMode(ValueAnimator.RESTART);
82 | }
83 | switch (engine.getColorList().size()) {
84 | case 0:
85 | return 0xff39c5bb;
86 | case 1:
87 | return engine.getColorList().get(0);
88 | default:
89 | if (anime.isRunning()) {
90 | if (isInterval)
91 | return fade[0];
92 | else
93 | return evaluate(anime.getAnimatedFraction(), fade);
94 | } else if (isInterval) {
95 | //进入渐变
96 | int readyIndex=index + 1;
97 | if (readyIndex >= engine.getColorList().size())
98 | readyIndex = 0;
99 | fade[0] = engine.getColorList().get(index);
100 | fade[1] = engine.getColorList().get(readyIndex);
101 | anime.setDuration(getEngine().getPreference().getInt("nenofade", 2) * 1000);
102 | isInterval = false;
103 | handler.sendEmptyMessage(0);
104 |
105 | } else {
106 | index++;
107 | if (index >= engine.getColorList().size())
108 | index = 0;
109 | fade[0] = (engine.getColorList().get(index));
110 | isInterval = true;
111 | anime.setDuration(getEngine().getPreference().getInt("nenointerval", 5) * 1000);
112 | handler.sendEmptyMessage(0);
113 | }
114 | return fade[0];
115 | }
116 | }
117 |
118 | @Override
119 | public float getInterpolator(float interpolator) {
120 | if (draw == null)return interpolator;
121 | return draw.getInterpolation(interpolator);
122 | }
123 |
124 |
125 | public void draw(Canvas canvas) {
126 | color_step = 0;
127 | if (draw != null)
128 | onDraw(canvas, Integer.parseInt(draw.getColorMode()));
129 | }
130 |
131 | public Integer evaluate(float fraction, int... n) {
132 | return (Integer)argb.evaluate(fraction, n[0], n[1]);
133 | /*int p2=n[0];
134 | int p3=n[1];
135 | int startA=Color.alpha(p2);
136 | int endA=Color.alpha(p3);
137 | int startRed = Color.red(p2);
138 | int startGreen = Color.green(p2);
139 | int startBlue = Color.blue(p2);
140 | int endRed = Color.red(p3);
141 | int endGreen = Color.green(p3);
142 | int endBlue = Color.blue(p3);
143 |
144 | int alpha=getCurrentColor(startA,endA,fraction);
145 | int red=getCurrentColor(startRed,endRed,fraction);
146 | int green=getCurrentColor(startGreen,endGreen,fraction);
147 | int blue=getCurrentColor(startBlue,endBlue,fraction);
148 |
149 | return Color.argb(alpha,red,green,blue);*/
150 | }
151 |
152 | /*private int getCurrentColor(int start, int end,float fraction) {
153 | return start-(int)((start-end)*fraction);
154 | }*/
155 |
156 |
157 |
158 |
159 | @Override
160 | public void setOffsetX(int x) {
161 | // TODO: Implement this method
162 | }
163 |
164 | @Override
165 | public void setOffsetY(int y) {
166 | // TODO: Implement this method
167 | }
168 |
169 | @Override
170 | public void finalized() {
171 | draw = null;
172 | anime = null;
173 | engine = null;
174 | finalize = true;
175 | }
176 |
177 | @Override
178 | public boolean isFinalized() {
179 | // TODO: Implement this method
180 | return finalize;
181 | }
182 |
183 | @Override
184 | protected void finalize() throws Throwable {
185 | super.finalize();
186 | finalized();
187 | }
188 |
189 | @Override
190 | public void checkMode(int mode, Paint paint) {
191 | final LiveWallpaper.WallpaperEngine engine=getEngine();
192 | if (getEngine() == null)return;
193 | final ColorList colorList=engine.getColorList();
194 | if (colorList == null)return;
195 | switch (mode) {
196 | case 1:
197 | paint.setColor(colorList.get(color_step));
198 | color_step++;
199 | if (color_step >= colorList.size())
200 | color_step = 0;
201 |
202 | break;
203 | case 2:
204 | paint.setColor(0xff000000 | (int)(Math.random() * 0xffffff));
205 | break;
206 | case 4:
207 | int color=colorList.get(color_step);
208 | paint.setColor(engine.getPreference().getBoolean("nenosync", false) ?color: 0xffffffff);
209 | color_step++;
210 | if (color_step >= colorList.size())
211 | color_step = 0;
212 | paint.setShadowLayer(paint.getStrokeWidth(), 0, 0, color);
213 | break;
214 | }
215 | }
216 |
217 |
218 | }
219 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/draw/circle/RingDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.draw.circle;
2 | import com.moe.LiveVisualizer.internal.ImageDraw;
3 | import com.moe.LiveVisualizer.service.LiveWallpaper;
4 | import android.graphics.Paint;
5 | import android.graphics.Canvas;
6 | import android.graphics.PointF;
7 | import android.graphics.Bitmap;
8 | import android.graphics.Matrix;
9 | import android.graphics.PorterDuffXfermode;
10 | import android.graphics.PorterDuff;
11 | import com.moe.LiveVisualizer.internal.OnColorSizeChangedListener;
12 | import android.graphics.Shader;
13 | import android.util.TypedValue;
14 | import com.moe.LiveVisualizer.draw.CircleDraw;
15 | import com.moe.LiveVisualizer.internal.ImageThread;
16 | import android.graphics.SweepGradient;
17 |
18 | public abstract class RingDraw extends CircleDraw implements OnColorSizeChangedListener
19 | {
20 | public final static int OUTSIDE=0;
21 | public final static int INSIDE=1;
22 | private int direction;
23 | private Paint paint;
24 | private float degress=0,vDegress=0;
25 | private float radius,degress_step;//圆形半径
26 | private boolean cutCenterImage,antialias;
27 | private ImageDraw draw;
28 | private Shader shader;
29 | private Bitmap shaderBuffer;
30 | private int borderHeight,size;
31 | private float spaceWidth,borderWidth;
32 |
33 | public RingDraw(ImageDraw draw){
34 | super(draw);
35 | LiveWallpaper.WallpaperEngine engine=getEngine();
36 | this.draw=draw;
37 | borderHeight = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, engine.getPreference().getInt("borderHeight", 100), engine.getContext().getResources().getDisplayMetrics());
38 | spaceWidth = engine.getPreference().getInt("spaceWidth", 20);
39 | direction=Integer.parseInt(engine.getPreference().getString("direction",OUTSIDE+""));
40 | paint = new Paint();
41 | //paint.setStrokeCap(getEngine().getPreference().getBoolean("round",true)?Paint.Cap.ROUND:Paint.Cap.SQUARE);
42 | paint.setColor(0xff39c5bb);
43 | borderWidth=(engine.getPreference().getInt("borderWidth",30));
44 | radius=engine.getPreference().getInt("circleRadius",Math.min(engine.getDisplayWidth(),engine.getDisplayHeight())/6);
45 | cutCenterImage=engine.getPreference().getBoolean("cutImage",true);
46 | degress_step=engine.getPreference().getInt("degress",10)/100f*10;
47 | engine.registerColorSizeChangedListener(this);
48 | onSizeChanged();
49 | }
50 |
51 | @Override
52 | public void setAntialias(boolean antialias)
53 | {
54 | this.antialias=antialias;
55 | //paint.setAntiAlias(antialias);
56 | }
57 |
58 |
59 | public float getBorderHeight(){
60 | return borderHeight;
61 | }
62 | public float getSpaceWidth(){
63 | return spaceWidth;
64 | }
65 | @Override
66 | public void onBorderHeightChanged(int height)
67 | {
68 | borderHeight = height;
69 | }
70 |
71 | @Override
72 | public void notifySizeChanged()
73 | {
74 | super.notifySizeChanged();
75 | shader=null;
76 | if(shaderBuffer!=null)
77 | shaderBuffer.recycle();
78 | shaderBuffer=null;
79 | onSizeChanged();
80 | }
81 |
82 | @Override
83 | public void onSpaceWidthChanged(int space)
84 | {
85 | spaceWidth = space;
86 | onSizeChanged();
87 | }
88 |
89 | @Override
90 | public void setNum(int num) {
91 | super.setNum(num);
92 | onSizeChanged();
93 | }
94 |
95 | @Override
96 | public int size()
97 | {
98 | return super.getSize();
99 | }
100 | public void onSizeChanged()
101 | {
102 | try
103 | {
104 | size = (int)(2*getRadius()*Math.PI/spaceWidth);
105 | }
106 | catch (Exception e)
107 | {}
108 | try
109 | {
110 | size = size > getEngine().getFftSize() ?getEngine().getFftSize(): size;
111 | }
112 | catch (Exception e)
113 | {}
114 |
115 | }
116 |
117 | @Override
118 | public void onBorderWidthChanged(int width)
119 | {
120 | this.borderWidth=width;
121 | onSizeChanged();
122 | }
123 | public float getBorderWidth(){
124 | return borderWidth;
125 | }
126 | public void setShader(Shader shader)
127 | {
128 | this.shader = shader;
129 | }
130 |
131 | public Shader getShader()
132 | {
133 | return shader;
134 | }
135 |
136 | public Bitmap getShaderBuffer(int width,int height)
137 | {
138 | if(!isFinalized()&&shaderBuffer==null){
139 | if(shader==null)
140 | shader=new SweepGradient(getPointF().x, getPointF().y, getEngine().getColorList().toArray(), null);
141 | shaderBuffer= Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
142 | Canvas shaderCanvas=new Canvas(shaderBuffer);
143 | paint.reset();
144 | paint.setShader(getShader());
145 | shaderCanvas.drawRect(0, 0, shaderCanvas.getWidth(), shaderCanvas.getHeight(), paint);
146 | paint.reset();
147 | }
148 | return shaderBuffer;
149 | }
150 | public Matrix getCenterScale()
151 | {
152 | if(draw==null)
153 | return null;
154 | return draw.getCenterScale();
155 | }
156 |
157 | public void setDirection(int direction){
158 | this.direction=direction;
159 | }
160 | public int getDirection(){
161 | return direction;
162 | }
163 | public void setRadius(int radius)
164 | {
165 | this.radius=radius;
166 | }
167 | public void setDegressStep(float step){
168 | degress_step=step;
169 | }
170 |
171 | final public void setCutImage(boolean cut)
172 | {
173 | cutCenterImage=cut;
174 | }
175 | final public Paint getPaint(){
176 | return paint;
177 | }
178 |
179 | @Override
180 | public void onDraw(Canvas canvas, int color_mode) throws NullPointerException
181 | {
182 | if(isFinalized())return;
183 | int count=-1;
184 | if(isVisualizerRotation()){
185 | count=canvas.save();
186 | canvas.rotate(vDegress+=degress_step,getPointF().x,getPointF().y);
187 | if(vDegress>=360)vDegress=0;
188 | }
189 | Paint paint=getPaint();
190 | paint.setStrokeCap(getRound());
191 | paint.setAntiAlias(antialias);
192 | paint.setDither(antialias);
193 | switch(color_mode){
194 | case 0:
195 | switch ( getEngine().getColorList().size() )
196 | {
197 | case 0:
198 | paint.setColor(0xff39c5bb);
199 | drawGraph(getFft(), canvas, color_mode,false);
200 | break;
201 | case 1:
202 | paint.setColor(getEngine().getColorList().get(0));
203 | drawGraph(getFft(), canvas, color_mode,false);
204 | break;
205 | default:
206 | final int layer=canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
207 | drawGraph(getFft(), canvas, color_mode,false);
208 | paint.reset();
209 | Bitmap buffer=getShaderBuffer(canvas.getWidth(),canvas.getHeight());
210 | if(buffer!=null&&!buffer.isRecycled()){
211 | //paint.setStyle(Paint.Style.FILL);
212 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
213 | canvas.drawBitmap(buffer, 0, 0, paint);
214 | //paint.setXfermode(null);
215 | }
216 | canvas.restoreToCount(layer);
217 | break;
218 | }
219 | break;
220 | case 1:
221 | case 2:
222 | if(getEngine()!=null)
223 | switch ( getEngine().getColorList().size() )
224 | {
225 | case 0:
226 | paint.setColor(0xff39c5bb);
227 | break;
228 | default:
229 | paint.setColor(getEngine().getColorList().get(0));
230 | break;
231 | }
232 | case 4:
233 | drawGraph(getFft(), canvas, color_mode,true);
234 | break;
235 | case 3:
236 | int color=getColor();
237 | try{
238 | paint.setColor(getEngine().getPreference().getBoolean("nenosync",false)?color:0xffffffff);
239 | }catch(NullPointerException e){}
240 | paint.setShadowLayer(getBorderWidth(),0,0,color);
241 | drawGraph(getFft(), canvas, color_mode,false);
242 | paint.clearShadowLayer();
243 | break;
244 | }
245 | paint.reset();
246 | if(count!=-1)
247 | canvas.restoreToCount(count);
248 | }
249 |
250 |
251 | public void drawCircleImage(Canvas canvas){
252 | final LiveWallpaper.WallpaperEngine engine=getEngine();
253 | if(engine==null)return;
254 | final ImageThread image=engine.getCircleImage();
255 | if(image==null)return;
256 | final Bitmap circle=image.getImage();
257 | if(circle==null||circle.isRecycled())return;
258 | final int layer=canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),null,canvas.ALL_SAVE_FLAG);
259 | PointF point=getPointF();
260 | //canvas.drawColor(0xffffffff);
261 | if(engine.getPreference().getBoolean("circleSwitch",true)){
262 | degress+=degress_step;
263 | if ( degress >= 360 )degress = 0;
264 | }
265 | canvas.rotate(degress,point.x,point.y);
266 | if(getCenterScale()!=null){
267 | Matrix matrix=getCenterScale();
268 | float scale=Math.max(radius*2/circle.getWidth(),radius*2/circle.getHeight());
269 | matrix.setScale(scale,scale);
270 | matrix.postTranslate(point.x-circle.getWidth()*scale/2,point.y-circle.getHeight()*scale/2);
271 | }
272 | try{
273 | if(cutCenterImage){
274 | canvas.drawCircle(point.x,point.y, radius, paint);
275 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
276 | if(getCenterScale()!=null)
277 | canvas.drawBitmap(circle,getCenterScale(),paint);
278 | else
279 | canvas.drawBitmap(circle,point.x-circle.getWidth()/2,point.y-circle.getHeight()/2, paint);
280 | paint.setXfermode(null);
281 | }else{
282 | if(getCenterScale()!=null)
283 | canvas.drawBitmap(circle,getCenterScale(),paint);
284 | else
285 | canvas.drawBitmap(circle,point.x-circle.getWidth()/2,point.y-circle.getHeight()/2, paint);
286 | }
287 | }catch(Exception e){}
288 | canvas.restoreToCount(layer);
289 | }
290 | public float getRadius(){
291 | return radius;
292 | }
293 |
294 | @Override
295 | public void finalized()
296 | {
297 | draw=null;
298 | onColorSizeChanged();
299 | if(getEngine()!=null)
300 | getEngine().unRegisterOnColorSizeChanged(this);
301 | paint.reset();
302 | super.finalized();
303 |
304 | }
305 | @Override
306 | public void onColorSizeChanged()
307 | {
308 | shader = null;
309 | if ( shaderBuffer != null )
310 | shaderBuffer.recycle();
311 | shaderBuffer = null;
312 | }
313 |
314 | @Override
315 | public void setOffsetX(int x)
316 | {
317 | // TODO: Implement this method
318 | super.setOffsetX(x);
319 | onColorSizeChanged();
320 | }
321 |
322 | @Override
323 | public void setOffsetY(int y)
324 | {
325 | // TODO: Implement this method
326 | super.setOffsetY(y);
327 | onColorSizeChanged();
328 | }
329 |
330 | }
331 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/activity/SettingActivity.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.activity;
2 | import android.app.Activity;
3 | import android.os.Bundle;
4 | import android.app.Fragment;
5 | import android.content.Intent;
6 | import android.app.WallpaperManager;
7 | import android.content.ComponentName;
8 | import android.app.WallpaperInfo;
9 | import android.widget.Toast;
10 | import android.net.Uri;
11 | import android.view.MenuItem;
12 | import android.content.ActivityNotFoundException;
13 | import android.provider.Settings;
14 | import android.content.pm.PermissionInfo;
15 | import android.content.pm.PermissionGroupInfo;
16 | import android.content.pm.PackageManager;
17 | import android.os.Build;
18 | import android.app.AlertDialog;
19 | import android.content.DialogInterface;
20 | import android.view.Menu;
21 | import com.moe.LiveVisualizer.R;
22 | import com.moe.LiveVisualizer.service.LiveWallpaper;
23 | import com.moe.LiveVisualizer.fragment.SettingFragment;
24 | import com.moe.LiveVisualizer.fragment.CircleSettingFragment;
25 | import com.moe.LiveVisualizer.fragment.DuangSettingFragment;
26 | import android.content.SharedPreferences;
27 | import android.content.ContentValues;
28 | import android.widget.FrameLayout;
29 | import android.view.Window;
30 |
31 | public class SettingActivity extends Activity implements SharedPreferences.OnSharedPreferenceChangeListener
32 | {
33 | private MenuItem centerCircle,duang;
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState)
36 | {
37 | super.onCreate(savedInstanceState);
38 | if (Intent.ACTION_MAIN.equals(getIntent().getAction()))
39 | init();
40 | else
41 | {
42 | Toast.makeText(this, "别点了,进不来的", Toast.LENGTH_SHORT).show();
43 | finish();}
44 | }
45 | private void init()
46 | {
47 | ComponentName service=new ComponentName(this, LiveWallpaper.class);
48 | if (Build.VERSION.SDK_INT < 23 || checkSelfPermission("android.permission.RECORD_AUDIO") == PackageManager.PERMISSION_GRANTED)
49 | {
50 | /*if ( Build.VERSION.SDK_INT > 18 && !notificationListenerEnable() )
51 | {
52 | gotoNotificationAccessSetting();
53 | return;
54 | }*/
55 | if (getPackageManager().getComponentEnabledSetting(service) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
56 | {
57 | getPackageManager().setComponentEnabledSetting(service, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
58 | }
59 | WallpaperInfo info=((WallpaperManager)getSystemService(WALLPAPER_SERVICE)).getWallpaperInfo();
60 | if (info == null || !getPackageName().equals(info.getPackageName()))
61 | {
62 | Toast.makeText(getApplicationContext(), "先激活动态壁纸才能继续使用", Toast.LENGTH_LONG).show();
63 | try
64 | {
65 | Intent intent =new Intent(
66 | WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
67 | intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
68 | new ComponentName(this, LiveWallpaper.class));
69 | startActivity(intent);
70 | }
71 | catch (Exception e1)
72 | {
73 | try
74 | {
75 | startActivity(new Intent(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER));
76 | }
77 | catch (Exception e)
78 | {
79 | AlertDialog dialog= new AlertDialog.Builder(this).setMessage("无法打开动态壁纸设置界面,你仍然可以通过设置来启用").create();
80 | dialog.setOnDismissListener(new DialogInterface.OnDismissListener(){
81 |
82 | @Override
83 | public void onDismiss(DialogInterface p1)
84 | {
85 | // TODO: Implement this method
86 | finish();
87 | }
88 | });
89 | dialog.show();
90 | }
91 |
92 | }
93 | finish();
94 | }
95 | else
96 | {
97 | FrameLayout frame=new FrameLayout(this);
98 | frame.setFitsSystemWindows(true);
99 | frame.setId(android.R.id.widget_frame);
100 | ((FrameLayout)findViewById(android.R.id.content)).addView(frame);
101 | Fragment setting=getFragmentManager().findFragmentByTag("setting");
102 | if (setting == null)
103 | {
104 | setting = new SettingFragment();
105 | if (setting.isAdded())
106 | getFragmentManager().beginTransaction().show(setting).commit();
107 | else
108 | getFragmentManager().beginTransaction().add(android.R.id.widget_frame, setting, "setting").show(setting).commit();
109 | }
110 | if(getActionBar()!=null){
111 | getActionBar().setDisplayHomeAsUpEnabled(true);
112 | getActionBar().setHomeButtonEnabled(true);
113 | }
114 | getSharedPreferences("moe",0).registerOnSharedPreferenceChangeListener(this);
115 | }
116 | }
117 | else
118 | {
119 | if (getPackageManager().getComponentEnabledSetting(service) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED)
120 | {
121 | getPackageManager().setComponentEnabledSetting(service, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
122 | }
123 | requestPermissions(new String[]{"android.permission.RECORD_AUDIO","android.permission.READ_PHONE_STATE"}, 432);
124 | }
125 | }
126 |
127 | @Override
128 | public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
129 | {
130 | // TODO: Implement this method
131 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
132 | if (requestCode == 432)
133 | {
134 | boolean flag=true;
135 | for (int grant:grantResults)
136 | {
137 | if (grant == PackageManager.PERMISSION_DENIED)
138 | flag = false;
139 | break;
140 | }
141 | if (flag)
142 | init();
143 | else
144 | {
145 | Toast.makeText(getApplicationContext(), "未给权限,已退出", Toast.LENGTH_LONG).show();
146 | finish();
147 | }
148 | }
149 | }
150 |
151 | @Override
152 | public boolean onCreateOptionsMenu(Menu menu)
153 | {
154 | centerCircle = menu.add(0, 0, 0, "中心圆");
155 | centerCircle.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
156 | duang=menu.add(1,1,1,"屏幕特效");
157 | duang.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
158 | Fragment fragment=getFragmentManager().findFragmentByTag("setting");
159 | centerCircle.setVisible(fragment != null && !fragment.isHidden());
160 | duang.setVisible(fragment!=null&&!fragment.isHidden());
161 | return true;
162 | }
163 |
164 |
165 |
166 |
167 |
168 | @Override
169 | public boolean onOptionsItemSelected(MenuItem item)
170 | {
171 | switch (item.getItemId())
172 | {
173 | case android.R.id.home:
174 | onBackPressed();
175 | return true;
176 | case 0:
177 | centerCircle.setVisible(false);
178 | duang.setVisible(false);
179 | Fragment circle_setting=getFragmentManager().findFragmentByTag("circle_setting");
180 | if (circle_setting == null)circle_setting = new CircleSettingFragment();
181 | if (circle_setting.isAdded())
182 | getFragmentManager().beginTransaction().hide(getFragmentManager().findFragmentByTag("setting")).show(circle_setting).commit();
183 | else
184 | getFragmentManager().beginTransaction().hide(getFragmentManager().findFragmentByTag("setting")).add(android.R.id.widget_frame, circle_setting, "circle_setting").commit();
185 |
186 | return true;
187 | case 1:
188 | centerCircle.setVisible(false);
189 | duang.setVisible(false);
190 | Fragment duang_setting=getFragmentManager().findFragmentByTag("daung_setting");
191 | if (duang_setting == null)duang_setting = new DuangSettingFragment();
192 | if (duang_setting.isAdded())
193 | getFragmentManager().beginTransaction().hide(getFragmentManager().findFragmentByTag("setting")).show(duang_setting).commit();
194 | else
195 | getFragmentManager().beginTransaction().hide(getFragmentManager().findFragmentByTag("setting")).add(android.R.id.widget_frame, duang_setting, "duang_setting").commit();
196 |
197 | break;
198 | }
199 | return super.onOptionsItemSelected(item);
200 | }
201 |
202 | @Override
203 | public void onBackPressed()
204 | {
205 | Fragment circle_setting=getFragmentManager().findFragmentByTag("circle_setting");
206 | Fragment duang_setting=getFragmentManager().findFragmentByTag("duang_setting");
207 | if (circle_setting != null && !circle_setting.isHidden())
208 | {
209 | getFragmentManager().beginTransaction().hide(circle_setting).show(getFragmentManager().findFragmentByTag("setting")).commit();
210 | if (centerCircle != null)centerCircle.setVisible(true);
211 | if(duang!=null)duang.setVisible(true);
212 | }
213 | else if(duang_setting!=null&&!duang_setting.isHidden()){
214 | getFragmentManager().beginTransaction().hide(duang_setting).show(getFragmentManager().findFragmentByTag("setting")).commit();
215 | if (centerCircle != null)centerCircle.setVisible(true);
216 | if(duang!=null)duang.setVisible(true);
217 | }else
218 | super.onBackPressed();
219 | }
220 |
221 | @Override
222 | public void onSharedPreferenceChanged(SharedPreferences p1, String p2)
223 | {
224 | Uri.Builder build=new Uri.Builder();
225 | build.scheme("content").authority("moe").path("moe").appendQueryParameter("key",p2).appendQueryParameter("value",p1.getAll().get(p2)+"");
226 | getContentResolver().update(build.build(),new ContentValues(),null,null);
227 | }
228 |
229 | @Override
230 | public void finish()
231 | {
232 | // TODO: Implement this method
233 | super.finish();
234 | getSharedPreferences("moe",0).unregisterOnSharedPreferenceChangeListener(this);
235 | }
236 |
237 |
238 | /*private void gotoNotificationAccessSetting()
239 | {
240 | try
241 | {
242 | final Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
243 | intent.putExtra("package", getPackageName());
244 | intent.putExtra("uid", getApplicationInfo().uid);
245 |
246 | startActivity(intent);
247 | }
248 | catch (ActivityNotFoundException e)
249 | { try
250 | {
251 | final Intent intent = new Intent();
252 | final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.Settings$NotificationAccessSettingsActivity");
253 | intent.setComponent(cn);
254 | intent.putExtra(":settings:show_fragment", "NotificationAccessSettings");
255 | startActivity(intent);
256 | }
257 | catch (Exception ex)
258 | {
259 | return;
260 | }
261 | }
262 | finish();
263 | }
264 | private boolean notificationListenerEnable()
265 | {
266 | boolean enable = false;
267 | String flat= Settings.Secure.getString(getContentResolver(), "enabled_notification_listeners");
268 | if ( flat != null )
269 | {
270 | enable = flat.contains(NotifycationListener.class.getName());
271 | }
272 | return enable;
273 | } */
274 |
275 | }
276 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/internal/ImageDraw.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.internal;
2 | import com.moe.LiveVisualizer.draw.*;
3 | import com.moe.LiveVisualizer.draw.circle.*;
4 | import com.moe.LiveVisualizer.draw.line.*;
5 |
6 | import com.moe.LiveVisualizer.service.LiveWallpaper;
7 | import com.moe.LiveVisualizer.inter.Draw;
8 | import com.moe.LiveVisualizer.service.LiveWallpaper.WallpaperEngine;
9 | import android.view.animation.AccelerateInterpolator;
10 | import android.view.animation.CycleInterpolator;
11 | import android.graphics.Shader;
12 | import android.graphics.Matrix;
13 | import android.view.animation.Interpolator;
14 | import android.graphics.LinearGradient;
15 | import android.view.animation.BaseInterpolator;
16 | import android.view.animation.OvershootInterpolator;
17 | import android.view.animation.AccelerateDecelerateInterpolator;
18 |
19 | public class ImageDraw extends BaseInterpolator implements OnColorSizeChangedListener
20 | {
21 | private LiveWallpaper.WallpaperEngine engine;
22 | //private Draw[] drawList=new Draw[13];
23 | private Shader shader;
24 | private float downSpeed;
25 | private Matrix centerImageMatrix;
26 | private String mode,color_mode;
27 | private WallpaperThread wallpaper;
28 | private Draw draw;
29 | private boolean antialias;
30 | private boolean rotation;
31 | private Interpolator mInterpolator;
32 | public ImageDraw(WallpaperThread wallpaper)
33 | {
34 | this.wallpaper=wallpaper;
35 | this.engine = wallpaper.getEngine();
36 | color_mode = engine.getPreference().getString("color_mode", "0");
37 | engine.registerColorSizeChangedListener(this);
38 | setMode(engine.getPreference().getString("visualizer_mode", "0"));
39 | mInterpolator=new AccelerateInterpolator();
40 | }
41 |
42 | public void setVisualizerRotation(boolean rotation)
43 | {
44 | this.rotation=rotation;
45 | if(draw instanceof CircleDraw)
46 | ((CircleDraw)draw).setVisualizerRotation(rotation);
47 | }
48 | public void setAnitialias(boolean antialias){
49 | this.antialias=antialias;
50 | if(draw!=null)draw.setAntialias(antialias);
51 | }
52 | @Override
53 | public float getInterpolation(float input){
54 | //return value*value*getDownSpeed(););
55 | //return mInterpolator.getInterpolation(input);
56 | return (1f- ((1.0f - input) * (1.0f - input)))*getDownSpeed();
57 | }
58 | public LiveWallpaper.WallpaperEngine getEngine()
59 | {
60 | return engine;
61 | }
62 | public void setMode(String mode)
63 | {
64 | this.mode = mode;
65 | if(draw!=null)draw.finalized();
66 | draw=null;
67 | }
68 | public WallpaperThread getWallpaperThread()
69 | {
70 | return wallpaper;
71 | }
72 | public void setColorMode(String mode)
73 | {
74 | this.color_mode = mode;
75 | }
76 | public String getColorMode()
77 | {
78 | return color_mode;
79 | }
80 | public void notifySizeChanged()
81 | {
82 | shader = null;
83 | if(draw!=null)draw.notifySizeChanged();
84 | /*for (Draw draw:drawList)
85 | if (draw != null)
86 | draw.notifySizeChanged();*/
87 | }
88 | public void setNum(int num){
89 | if(draw!=null)
90 | draw.setNum(num);
91 | }
92 | public void setDirection(int direction)
93 | {
94 | if(draw instanceof RingDraw)
95 | ((RingDraw)draw).setDirection(direction);
96 | /*for (Draw draw:drawList)
97 | if (draw instanceof RingDraw)
98 | ((RingDraw)draw).setDirection(direction);*/
99 | }
100 | public void setCircleRadius(int radius)
101 | {
102 | if(draw instanceof RingDraw)
103 | ((RingDraw)draw).setRadius(radius);
104 | /*for (Draw draw:drawList)
105 | if (draw instanceof RingDraw)
106 | ((RingDraw)draw).setRadius(radius);*/
107 | }
108 | public void setDegressStep(float step)
109 | {
110 | if(draw instanceof RingDraw)
111 | ((RingDraw)draw).setDegressStep(step);
112 | /*for (Draw draw:drawList)
113 | if (draw instanceof RingDraw)
114 | ((RingDraw)draw).setDegressStep(step);*/
115 | }
116 | public void setOffsetY(int y)
117 | {
118 | if(draw!=null)
119 | draw.setOffsetY(y);
120 | /*for (Draw draw:drawList)
121 | if (draw != null)
122 | draw.setOffsetY(y);*/
123 | }
124 |
125 | public void setOffsetX(int x)
126 | {
127 | if(draw!=null)
128 | draw.setOffsetX(x);
129 | /*for (Draw draw:drawList)
130 | if (draw != null)
131 | draw.setOffsetX(x);*/
132 | }
133 | public void setCenterScale(boolean scale)
134 | {
135 | if (scale)
136 | centerImageMatrix = new Matrix();
137 | else
138 | centerImageMatrix = null;
139 | }
140 | public Matrix getCenterScale()
141 | {
142 | return centerImageMatrix;
143 | }
144 | public void setCutImage(boolean cut)
145 | {
146 | if(draw instanceof RingDraw)
147 | ((RingDraw)draw).setCutImage(cut);
148 | /*for (Draw draw:drawList)
149 | if (draw instanceof RingDraw)
150 | ((RingDraw)draw).setCutImage(cut);*/
151 |
152 | }
153 |
154 | public void setRound(boolean round)
155 | {
156 | if(draw!=null)
157 | draw.setRound(round);
158 | /*for (Draw draw:drawList)
159 | if (draw != null)
160 | draw.setRound(round);*/
161 | }
162 |
163 | public void setDownSpeed(int speed)
164 | {
165 | downSpeed =speed/50f;
166 | }
167 | private float getDownSpeed()
168 | {
169 | return downSpeed;
170 | }
171 | public void setDrawHeight(float height)
172 | {
173 | if(draw!=null)
174 | draw.onDrawHeightChanged(height);
175 | /*for (Draw draw:drawList)
176 | if (draw != null)
177 | draw.onDrawHeightChanged(height);*/
178 | }
179 | public void setBorderHeight(int height)
180 | {
181 | if(draw!=null)
182 | draw.onBorderHeightChanged(height);
183 | /*for (Draw draw:drawList)
184 | if (draw != null)
185 | draw.onBorderHeightChanged(height);*/
186 | }
187 | public void setSpaceWidth(int space)
188 | {
189 | if(draw!=null)
190 | draw.onSpaceWidthChanged(space);
191 | /*for (Draw draw:drawList)
192 | if (draw != null)
193 | draw.onSpaceWidthChanged(space);*/
194 | }
195 | public void setBorderWidth(int width)
196 | {
197 | if(draw!=null)
198 | draw.onBorderWidthChanged(width);
199 | /*for (Draw draw:drawList)
200 | if (draw != null)
201 | draw.onBorderWidthChanged(width);*/
202 | }
203 | @Override
204 | public void onColorSizeChanged()
205 | {
206 | shader = null;
207 | }
208 | public byte[] getWave()
209 | {
210 |
211 | return wallpaper.getWave();
212 | }
213 | public double[] getFft()
214 | {
215 | return wallpaper.getFft();
216 | }
217 |
218 | final public Draw lockData()
219 | {
220 | if(draw==null){
221 | get();
222 | if(draw!=null){
223 | draw.setAntialias(antialias);
224 | }
225 | if(draw instanceof CircleDraw)
226 | ((CircleDraw)draw).setVisualizerRotation(rotation);
227 | }
228 | return draw;
229 |
230 | }
231 |
232 | private Draw get()
233 | {
234 | switch (mode)
235 | {
236 | case "0"://柱形图
237 | return draw=new RadialDraw(this);
238 | case "1"://折线图
239 | return draw= new LineChartDraw(this);
240 | case "2"://圆形射线
241 | return draw = new CircleRadialDraw(this);
242 | case "3"://弹弹圈
243 | return draw = new PopCircleDraw(this);
244 | case "4"://圆环三角
245 | return draw = new CircleTriangleDraw(this);
246 | case "5"://射线
247 | return draw = new CenterRadialDraw(this);
248 | case "6"://波纹
249 | return draw = new RippleDraw(this);
250 | case "7"://离散
251 | return draw = new CircleDisperseDraw(this);
252 | case "8"://山坡线
253 | return draw = new YamaLineDraw(this);
254 | case "9"://方块
255 | return draw = new SquareDraw(this);
256 | case "10"://打砖块
257 | return draw = new BlockBreakerDraw(this);
258 | case "11":
259 | return draw = new UnKnow1(this);
260 | case "12":
261 | return draw = new UnKnow2(this);
262 | case "13":
263 | return draw=new UnKnow3(this);
264 | case "14"://心形
265 | return draw=new HeartDraw(this);
266 | }
267 | return null;
268 | /*switch (mode)
269 | {
270 | case "0"://柱形图
271 | return drawList[0] == null ?drawList[0] = new RadialDraw(this): drawList[0];
272 | case "1"://折线图
273 | return drawList[1] == null ?drawList[1] = new LineChartDraw(this): drawList[1];
274 | case "2"://圆形射线
275 | return drawList[2] == null ?drawList[2] = new CircleRadialDraw(this): drawList[2];
276 | case "3"://弹弹圈
277 | return drawList[3] == null ?drawList[3] = new PopCircleDraw(this): drawList[3];
278 | case "4"://圆环三角
279 | return drawList[4] == null ?drawList[4] = new CircleTriangleDraw(this): drawList[4];
280 | case "5"://射线
281 | return drawList[5] == null ?drawList[5] = new CenterRadialDraw(this): drawList[5];
282 | case "6"://波纹
283 | return drawList[6] == null ?drawList[6] = new RippleDraw(this): drawList[6];
284 | case "7"://离散
285 | return drawList[7] == null ?drawList[7] = new CircleDisperseDraw(this): drawList[7];
286 | case "8"://山坡线
287 | return drawList[8] == null ?drawList[8] = new YamaLineDraw(this): drawList[8];
288 | case "9"://方块
289 | return drawList[9] == null ?drawList[9] = new SquareDraw(this): drawList[9];
290 | case "10"://打砖块
291 | return drawList[10] == null ?drawList[10] = new BlockBreakerDraw(this): drawList[10];
292 | case "11":
293 | return drawList[11] == null ?drawList[11] = new UnKnow1(this): drawList[11];
294 | case "12":
295 | return drawList[12] == null ?drawList[12] = new UnKnow2(this): drawList[12];
296 | }
297 | return null;*/
298 | }
299 | public void resetShader()
300 | {
301 | this.shader = null;
302 | }
303 | public synchronized Shader getShader()
304 | {
305 | if (shader == null)
306 | {
307 | switch (engine.getPreference().getString("color_direction", "0"))
308 | {
309 | case "0"://lefttoright
310 | shader = new LinearGradient(0, 0, engine.getDisplayWidth(), 0, engine.getColorList().toArray(), null, LinearGradient.TileMode.CLAMP);
311 | break;//righttoleft
312 | case "1":
313 | shader = new LinearGradient(engine.getDisplayWidth(), 0, 0, 0, engine.getColorList().toArray(), null, LinearGradient.TileMode.CLAMP);
314 |
315 | break;//toptobottom
316 | case "2":shader = new LinearGradient(0, 0, 0, engine.getDisplayHeight(), engine.getColorList().toArray(), null, LinearGradient.TileMode.CLAMP);
317 |
318 | break;//bottomtotop
319 | case "3":shader = new LinearGradient(0, engine.getDisplayHeight(), 0, 0, engine.getColorList().toArray(), null, LinearGradient.TileMode.CLAMP);
320 |
321 | break;//toplefttobottomright
322 | case "4":shader = new LinearGradient(0, 0, engine.getDisplayWidth(), engine.getDisplayHeight(), engine.getColorList().toArray(), null, LinearGradient.TileMode.CLAMP);
323 |
324 | break;//toprighttobottomleft
325 | case "5":shader = new LinearGradient(engine.getDisplayWidth(), 0, 0, engine.getDisplayHeight(), engine.getColorList().toArray(), null, LinearGradient.TileMode.CLAMP);
326 |
327 | break;//bottomlefttotopright
328 | case "6":shader = new LinearGradient(0, engine.getDisplayHeight(), engine.getDisplayWidth(), 0, engine.getColorList().toArray(), null, LinearGradient.TileMode.CLAMP);
329 |
330 | break;//bottomrighttotopright
331 | case "7":shader = new LinearGradient(engine.getDisplayWidth(), engine.getDisplayHeight(), 0, 0, engine.getColorList().toArray(), null, LinearGradient.TileMode.CLAMP);
332 |
333 | break;
334 | }
335 | }
336 | return shader;
337 | }
338 | }
339 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/fragment/CircleSettingFragment.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.fragment;
2 | import android.preference.PreferenceActivity;
3 | import android.os.PersistableBundle;
4 | import android.os.Bundle;
5 | import android.preference.PreferenceFragment;
6 | import android.preference.Preference;
7 | import android.app.ProgressDialog;
8 | import android.app.AlertDialog;
9 | import java.lang.ref.SoftReference;
10 | import android.net.Uri;
11 | import java.io.File;
12 | import android.content.DialogInterface;
13 | import android.content.Intent;
14 | import android.app.Activity;
15 | import java.lang.reflect.Field;
16 | import android.widget.ProgressBar;
17 | import java.io.FileOutputStream;
18 | import java.io.InputStream;
19 | import android.os.Build;
20 | import android.widget.Toast;
21 | import java.io.IOException;
22 | import android.os.Handler;
23 | import android.os.Message;
24 | import android.app.Dialog;
25 | import android.graphics.Bitmap;
26 | import android.util.DisplayMetrics;
27 | import android.view.WindowManager;
28 | import android.app.Service;
29 | import com.moe.LiveVisualizer.preference.SeekBarPreference;
30 | import com.moe.LiveVisualizer.R;
31 | import com.moe.LiveVisualizer.activity.CropActivity;
32 |
33 | public class CircleSettingFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener
34 | {
35 | private DisplayMetrics display;
36 |
37 | private final static int CIRCLE=0x03;
38 |
39 | private final static int CIRCLE_SUCCESS=0x06;
40 | private final static int CIRCLE_DISMISS=0x07;
41 | private ProgressDialog circle_dialog;
42 | private AlertDialog circle_delete;
43 | private SoftReference weak;
44 | @Override
45 | public void onActivityCreated(Bundle savedInstanceState)
46 | {
47 | // TODO: Implement this method
48 | super.onActivityCreated(savedInstanceState);
49 | display =new DisplayMetrics();
50 | ( (WindowManager)getActivity().getSystemService(Service.WINDOW_SERVICE)).getDefaultDisplay().getRealMetrics(display);
51 |
52 | getPreferenceManager().setSharedPreferencesName("moe");
53 | addPreferencesFromResource(R.xml.circle_setting);
54 | findPreference("circle_image").setOnPreferenceClickListener(this);
55 | int width=Math.min(display.widthPixels,display.heightPixels);
56 | int height=Math.max(display.widthPixels,display.heightPixels);
57 | SeekBarPreference offsetX=(SeekBarPreference)findPreference("offsetX");
58 | offsetX.setMax(width);
59 | offsetX.setDefaultValue(width/2);
60 | SeekBarPreference offsetY=(SeekBarPreference) findPreference("offsetY");
61 | offsetY.setMax(height);
62 | offsetY.setDefaultValue(height/2);
63 | SeekBarPreference circle_radius=(SeekBarPreference) findPreference("circleRadius");
64 | circle_radius.setMax(width);
65 | circle_radius.setDefaultValue(width/3);
66 | }
67 |
68 | @Override
69 | public boolean onPreferenceClick(Preference p1)
70 | {
71 | switch(p1.getKey()){
72 | case "circle_image":
73 | final File circle=new File(getActivity().getExternalFilesDir(null), "circle");
74 | if ( circle.exists() )
75 | {
76 | if ( circle_delete == null )
77 | {
78 | circle_delete = new AlertDialog.Builder(getActivity()).setTitle("确认").setMessage("是否清除当前图片?").setPositiveButton("取消", null).setNegativeButton("确定", new DialogInterface.OnClickListener(){
79 |
80 | @Override
81 | public void onClick(DialogInterface p1, int p2)
82 | {
83 | circle.delete();
84 | getActivity().sendBroadcast(new Intent("circle_changed"));
85 |
86 | }
87 | }).create();
88 | }
89 | circle_delete.show();
90 | }
91 | else
92 | {
93 | Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
94 | intent.setType("image/*");
95 | /*intent.putExtra("crop", "true");
96 | //width:height
97 | intent.putExtra("aspectX", 1);
98 | intent.putExtra("aspectY", 1);
99 | intent.putExtra("outputX", display.widthPixels / 3);
100 | intent.putExtra("outputY", display.widthPixels / 3);
101 | intent.putExtra("output", Uri.fromFile(circle));
102 | intent.putExtra("return-data", false);
103 | intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());*/
104 | try
105 | {startActivityForResult(Intent.createChooser(intent, "Choose Image"), CIRCLE);}
106 | catch (Exception e)
107 | {}
108 | }
109 | break;
110 | }
111 | return false;
112 | }
113 | @Override
114 | public void onActivityResult(int requestCode, int resultCode, final Intent data)
115 | {
116 | if ( resultCode == Activity.RESULT_OK )
117 | switch ( requestCode )
118 | {
119 | case CIRCLE:
120 | if(data.getData()==null)break;
121 | weak=new SoftReference(data.getData());
122 | if ( circle_dialog == null )
123 | {
124 | circle_dialog = new ProgressDialog(getActivity());
125 | circle_dialog.setMessage("如何处理图片");
126 | circle_dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
127 | circle_dialog.setButton(ProgressDialog.BUTTON1,"裁剪", new DialogInterface.OnClickListener(){
128 |
129 | @Override
130 | public void onClick(DialogInterface p1, int p2)
131 | {
132 | try{
133 | Field progressBar=circle_dialog.getClass().getDeclaredField("mProgress");
134 | progressBar.setAccessible(true);
135 | ((ProgressBar)progressBar.get(circle_dialog)).setVisibility(ProgressBar.VISIBLE);
136 | }catch(Exception e){}
137 | new Thread(){
138 | public void run()
139 | {
140 | final File tmp=new File(getActivity().getExternalFilesDir(null), "tmpImage");
141 | FileOutputStream fos=null;
142 | InputStream is=null;
143 | try
144 | {
145 | fos = new FileOutputStream(tmp);
146 | is = getActivity().getContentResolver().openInputStream(weak.get());
147 | byte[] buffer=new byte[16*1024];
148 | int len;
149 | while ( (len = is.read(buffer)) != -1 )
150 | fos.write(buffer, 0, len);
151 | fos.flush();
152 | final File circle_file=new File(getActivity().getExternalFilesDir(null), "circle");
153 | Intent intent = new Intent("com.android.camera.action.CROP");
154 | intent.setClass(getActivity(),CropActivity.class);
155 | /*if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.N )
156 | {
157 | intent.setDataAndType(FileProvider.getUriForFile(getActivity(), getActivity().getPackageName() + ".provider", tmp), "image/*");
158 | intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
159 | }
160 | else*/
161 | intent.setDataAndType(Uri.fromFile(tmp), "image/*");
162 |
163 | intent.putExtra("crop", "true");
164 | intent.putExtra("aspectX", 1);
165 | intent.putExtra("aspectY", 1);
166 | int width=Math.min(display.widthPixels,display.heightPixels)/3;
167 | intent.putExtra("outputX", width);
168 | intent.putExtra("outputY", width);
169 | intent.putExtra("output", Uri.fromFile(circle_file));
170 | intent.putExtra("return-data", false);
171 | intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
172 | try
173 | {
174 | startActivityForResult(intent, CIRCLE_SUCCESS);
175 | }
176 | catch (Exception e)
177 | {Toast.makeText(getActivity(),"请安装一个裁剪图片的软件",Toast.LENGTH_LONG).show();}
178 |
179 | }
180 | catch (Exception e)
181 | {}
182 | finally
183 | {
184 | try
185 | {
186 | if ( fos != null )fos.close();
187 | }
188 | catch (IOException e)
189 | {}
190 | try
191 | {
192 | if ( is != null )is.close();
193 | }
194 | catch (IOException e)
195 | {}
196 | }
197 | handler.obtainMessage(CIRCLE_DISMISS).sendToTarget();
198 | }
199 | }.start();
200 | }
201 | });
202 | circle_dialog.setButton(ProgressDialog.BUTTON2,"原图", new DialogInterface.OnClickListener(){
203 |
204 | @Override
205 | public void onClick(DialogInterface p1, int p2)
206 | {
207 | try{
208 | Field progressBar=circle_dialog.getClass().getDeclaredField("mProgress");
209 | progressBar.setAccessible(true);
210 | ((ProgressBar)progressBar.get(circle_dialog)).setVisibility(ProgressBar.VISIBLE);
211 | }catch(Exception e){}
212 | new Thread(){
213 | public void run(){
214 | final File tmp=new File(getActivity().getExternalFilesDir(null), "circle");
215 | FileOutputStream fos=null;
216 | InputStream is=null;
217 | try
218 | {
219 | fos = new FileOutputStream(tmp);
220 | is = getActivity().getContentResolver().openInputStream(weak.get());
221 | byte[] buffer=new byte[16*1024];
222 | int len;
223 | while ( (len = is.read(buffer)) != -1 )
224 | fos.write(buffer, 0, len);
225 | fos.flush();
226 | }
227 | catch (Exception e)
228 | {}
229 | finally
230 | {
231 | try
232 | {
233 | if ( fos != null )fos.close();
234 | }
235 | catch (IOException e)
236 | {}
237 | try
238 | {
239 | if ( is != null )is.close();
240 | }
241 | catch (IOException e)
242 | {}
243 | }
244 | getActivity().sendBroadcast(new Intent("circle_changed"));
245 | handler.obtainMessage(CIRCLE_DISMISS).sendToTarget();
246 | }
247 | }.start();
248 | }
249 | });
250 | circle_dialog.setButton(ProgressDialog.BUTTON3,"取消",handler.obtainMessage(CIRCLE_DISMISS));
251 | circle_dialog.setCanceledOnTouchOutside(false);
252 | }
253 | circle_dialog.show();
254 | try
255 | {
256 | Field progressBar=circle_dialog.getClass().getDeclaredField("mProgress");
257 | progressBar.setAccessible(true);
258 | ((ProgressBar)progressBar.get(circle_dialog)).setVisibility(ProgressBar.GONE);
259 | Field show=Dialog.class.getDeclaredField("mShowing");
260 | show.setAccessible(true);
261 | show.setBoolean(circle_dialog,false);
262 | }
263 | catch (Exception e)
264 | {}
265 | break;
266 | case CIRCLE_SUCCESS:
267 | getActivity().sendBroadcast(new Intent("circle_changed"));
268 | break;
269 | }
270 | }
271 | private Handler handler=new Handler(){
272 |
273 | @Override
274 | public void handleMessage(Message msg)
275 | {
276 | switch(msg.what){
277 | case CIRCLE_DISMISS:
278 | if(circle_dialog!=null){
279 | try{
280 | Field show=Dialog.class.getDeclaredField("mShowing");
281 | show.setAccessible(true);
282 | show.setBoolean(circle_dialog,true);
283 | }catch(Exception e){}
284 | circle_dialog.dismiss();
285 | }
286 | break;
287 | }
288 | }
289 |
290 | };
291 | }
292 |
--------------------------------------------------------------------------------
/app/src/main/java/com/moe/LiveVisualizer/activity/ColorListActivity.java:
--------------------------------------------------------------------------------
1 | package com.moe.LiveVisualizer.activity;
2 | import android.app.Activity;
3 | import android.os.Bundle;
4 | import android.view.Menu;
5 | import android.view.MenuItem;
6 | import android.app.AlertDialog;
7 | import com.moe.LiveVisualizer.widget.ColorPickerView;
8 | import android.content.SharedPreferences;
9 | import java.io.OutputStream;
10 | import android.os.Handler;
11 | import android.os.Message;
12 | import java.io.File;
13 | import java.io.BufferedReader;
14 | import java.io.InputStreamReader;
15 | import java.io.FileInputStream;
16 | import java.io.FileNotFoundException;
17 | import java.io.FileOutputStream;
18 | import java.io.IOException;
19 | import com.moe.LiveVisualizer.utils.ColorList;
20 | import android.widget.ListView;
21 | import com.moe.LiveVisualizer.adapter.ColorAdapter;
22 | import android.view.View;
23 | import android.widget.AdapterView;
24 | import android.widget.Adapter;
25 | import android.widget.PopupWindow;
26 | import android.widget.LinearLayout;
27 | import android.widget.TextView;
28 | import android.view.Gravity;
29 | import android.graphics.drawable.BitmapDrawable;
30 | import com.moe.LiveVisualizer.internal.ShadowDrawable;
31 | import android.view.ContextThemeWrapper;
32 | import com.moe.LiveVisualizer.widget.PopupLayout;
33 | import android.content.Intent;
34 | import android.widget.EditText;
35 | import android.content.DialogInterface;
36 | import android.graphics.Color;
37 | import com.moe.LiveVisualizer.app.ColorDialog;
38 | import android.widget.*;
39 | import android.net.*;
40 |
41 | public class ColorListActivity extends Activity implements ColorPickerView.OnColorCheckedListener,ListView.OnItemClickListener,View.OnClickListener
42 | {
43 | private ColorList colorList;
44 | private static final int INPUT=0;
45 | private AlertDialog colorPicker;
46 | private ListView listview;
47 | private Object fileLock=new Object();
48 | private PopupWindow popup;
49 | @Override
50 | protected void onCreate(Bundle savedInstanceState)
51 | {
52 | super.onCreate(savedInstanceState);
53 | colorList=new ColorList();
54 | listview=new ListView(this);
55 | listview.setAdapter(new ColorAdapter(colorList));
56 | listview.setOnItemClickListener(this);
57 | listview.setFitsSystemWindows(true);
58 | setContentView(listview);
59 | setTitle("色彩组");
60 | getActionBar().setDisplayHomeAsUpEnabled(true);
61 | getActionBar().setHomeButtonEnabled(true);
62 | read();
63 | }
64 |
65 | @Override
66 | public boolean onCreateOptionsMenu(Menu menu)
67 | {
68 | MenuItem item=menu.add(0,0,0,"手动输入");
69 | item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
70 | item=menu.add(1,1,1,"调色板");
71 | menu.add(2,2,2,"导入");
72 | menu.add(3,3,3,"导出");
73 | menu.add(4,4,4,"清空");
74 | //VectorDrawableCompat plus=VectorDrawableCompat.create(getResources(),R.drawable.plus,getTheme());
75 | //plus.setTint(0xffffffff);
76 | //item.setIcon(plus);
77 | item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
78 | return true;
79 | }
80 | @Override
81 | public boolean onOptionsItemSelected(MenuItem item)
82 | {
83 | switch(item.getItemId()){
84 | case android.R.id.home:
85 | finish();
86 | return true;
87 | case 0:
88 | if(colorPicker==null){
89 | final EditText view=new EditText(this);
90 | // view.setOnColorCheckedListener(this);
91 | colorPicker = new AlertDialog.Builder(this).setTitle("输入十六进制颜色").setView(view).setPositiveButton("取消", null).setNegativeButton("确定", new DialogInterface.OnClickListener(){
92 |
93 | @Override
94 | public void onClick(DialogInterface p1, int p2)
95 | {
96 | try{
97 | colorList.add( Color.parseColor(view.getText().toString()));
98 | ((ColorAdapter)listview.getAdapter()).notifyDataSetChanged();
99 | notifyColorFileChanged();
100 | }catch(Exception e){}
101 | }
102 | }).create();
103 | }
104 | colorPicker.show();
105 | break;
106 | case 1:
107 |
108 | ColorDialog cd=(ColorDialog) getFragmentManager().findFragmentByTag("color");
109 | if(cd==null){cd=new ColorDialog();
110 | cd.setOnColorCheckedListener(this);}
111 | if(cd.isAdded())getFragmentManager().beginTransaction().show(cd).commit();
112 | else cd.show(getFragmentManager(),"color");
113 | break;
114 | case 2:
115 | Intent intent=new Intent(Intent.ACTION_GET_CONTENT);
116 | intent.setType("*/*");
117 | startActivityForResult(intent,2534);
118 | break;
119 | case 3:
120 | if(colorList.isEmpty()){
121 | Toast.makeText(this,"没有数据",Toast.LENGTH_SHORT).show();
122 | }else{
123 | final File backup=getExternalFilesDir("backup");
124 | if(!backup.exists())
125 | backup.mkdirs();
126 | final EditText filename=new EditText(this);
127 | new AlertDialog.Builder(this).setTitle("文件命名").setView(filename).setPositiveButton("保存", new DialogInterface.OnClickListener(){
128 |
129 | @Override
130 | public void onClick(DialogInterface p1, int p2)
131 | {
132 | final File file=new File(backup,filename.getText().toString().trim().concat(".mcl"));
133 | if(file.exists()){
134 | Toast.makeText(ColorListActivity.this,"文件已存在",Toast.LENGTH_SHORT).show();
135 | return;
136 | }
137 | new Thread(){
138 | public void run(){
139 | save(file);
140 | runOnUiThread(new Runnable(){
141 |
142 | @Override
143 | public void run()
144 | {
145 | Toast.makeText(ColorListActivity.this,"保存成功\n".concat(backup.getAbsolutePath()),Toast.LENGTH_SHORT).show();
146 | }
147 | });
148 | }
149 | }.start();
150 | }
151 | }).setNegativeButton(android.R.string.cancel, null).show();
152 | }
153 | break;
154 | case 4:
155 | colorList.clear();
156 | ((ColorAdapter)listview.getAdapter()).notifyDataSetChanged();
157 | notifyColorFileChanged();
158 | break;
159 | }
160 | return super.onOptionsItemSelected(item);
161 | }
162 |
163 | @Override
164 | public void onColorChecked(int color)
165 | {
166 | colorList.add(color);
167 | ((ColorAdapter)listview.getAdapter()).notifyDataSetChanged();
168 | notifyColorFileChanged();
169 | //colorPicker.dismiss();
170 | ColorDialog cd=(ColorDialog) getFragmentManager().findFragmentByTag("color");
171 | if(cd!=null)cd.dismiss();
172 | }
173 |
174 | @Override
175 | public void onItemClick(AdapterView> p1, View p2, int p3, long p4)
176 | {
177 | if(popup==null){
178 | PopupLayout group=new PopupLayout(this);
179 | group.addView(new View(this),new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,p2.getHeight()));
180 | TextView remove=new TextView(this);
181 | remove.setText("移除");
182 | remove.setOnClickListener(this);
183 | remove.setGravity(Gravity.CENTER_VERTICAL);
184 | group.addView(remove,new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,p2.getHeight()));
185 | popup=new PopupWindow(p2.getContext());
186 | popup.setContentView(group);
187 | popup.setWidth(p2.getHeight()*2);
188 | popup.setHeight(p2.getHeight()*2);
189 | popup.setBackgroundDrawable(new ShadowDrawable());
190 | popup.setTouchable(true);
191 | popup.setOutsideTouchable(true);
192 | remove.setId(popup.hashCode());
193 | }
194 | ((PopupLayout)popup.getContentView()).getChildAt(0).setBackgroundColor(colorList.get(p3));
195 | popup.showAsDropDown(p2,(p2.getWidth()-p2.getHeight())/2,-(int)(p2.getHeight()/2.0f));
196 | popup.getContentView().setId(p3);
197 | }
198 |
199 |
200 | /*private Handler handler=new Handler(){
201 |
202 | @Override
203 | public void handleMessage(Message msg)
204 | {
205 | switch(msg.what){
206 | case INPUT:
207 | break;
208 | }
209 | }
210 |
211 | };*/
212 | private void notifyColorFileChanged(){
213 | new Thread(){
214 | public void run(){
215 | synchronized(fileLock){
216 | File colorFile=new File(getExternalFilesDir(null),"color");
217 | save(colorFile);
218 | }
219 | sendBroadcast(new Intent("color_changed"));
220 | }}.start();
221 | }
222 | private void save(File file){
223 | OutputStream os=null;
224 | try
225 | {
226 | os = new FileOutputStream(file);
227 | for(int i=0;i