Faire un joli widget de réglage de la luminosité

Il y a longtemps, ma mère avait une application sur le téléphone qui me permettait de changer la luminosité de l'écran en faisant glisser mon doigt le long de son bord gauche. Maman s'est habituée à lui, puis a changé de téléphone et cette application a déjà disparu du magasin. En fait, n'ayant pas trouvé d'analogues, j'ai décidé de l'écrire moi-même et de le lui donner pour son anniversaire. Un guide étape par étape pour créer et le résultat est dans cet article.

Pour créer cette application, nous avons besoin de deux autorisations - l'autorisation de modifier les paramètres du système (ajuster directement la luminosité) et l'autorisation de superposer sur d'autres applications. Ces deux autorisations depuis Android 6.0 ne peuvent pas être obtenues simplement en les spécifiant dans le manifeste - elles doivent être demandées séparément de l'utilisateur.

La structure de notre application sera la suivante - l'activité principale, qui aura deux boutons - l'un démarrera le service, qui attirera le SeekBar pour contrôler la luminosité, et le second arrêtera ce service. Commençons par notre activité principale. Voici à quoi ressemble le fichier de balisage:
Markup mainActivity
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/startService" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="27dp" android:text=" " /> <Button android:id="@+id/stopService" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/startService" android:layout_below="@+id/startService" android:layout_marginTop="39dp" android:text=" " /> </LinearLayout> 


Et voici à quoi ressemblera l'activité elle-même:
mainActivity
 import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.Settings; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //  ,   Android  ,    6   -     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES .M) { if (!Settings.System.canWrite(getApplicationContext())) { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName())); Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); startActivity(myIntent); startActivity(intent); } else { } } final Button startService = (Button) findViewById(R.id.startService); final Button stopService = (Button) findViewById(R.id.stopService); startService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startService(new Intent(getApplication(), BrightnessChekingService.class)); } }); stopService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stopService(new Intent(getApplication(), BrightnessChekingService.class)); } }); } } 


Créons maintenant le service BrightnessChekingService, ses fonctions que j'ai déjà indiquées ci-dessus. N'oubliez pas - si vous le créez manuellement, vous devez l'enregistrer dans le manifeste
LuminositéChekingService
 import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; import android.os.Build; import android.os.IBinder; import android.provider.Settings; import android.view.Gravity; import android.view.WindowManager; import android.widget.SeekBar; public class BrightnessChekingService extends Service{ private WindowManager windowManager; private WindowManager.LayoutParams params; private VerticalSeekBar seekBar; private Context context; public void onCreate () { super.onCreate(); //    ,     Android,          int LAYOUT_FLAG; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; } else { LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE; } windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); context = this.getApplicationContext(); seekBar = new VerticalSeekBar(context); seekBar.setMax(255); float alpha = (float) 0.1; seekBar.setAlpha(alpha); params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.MATCH_PARENT, LAYOUT_FLAG, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); params.gravity = Gravity.START; params.x = 0; params.y = 0; params.height = 700; windowManager.addView(seekBar, params); int Brightnes = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 0); seekBar.setProgress(Brightnes); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){ public void onProgressChanged(SeekBar seekBar, int i, boolean b) { Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS,i); //    ,      seekBar   Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); } public void onStartTrackingTouch(SeekBar seekBar) { } public void onStopTrackingTouch (SeekBar seekBar) { } }); } public void onDestroy() { super.onDestroy(); if (seekBar != null) windowManager.removeView(seekBar); } @Override public IBinder onBind(Intent intent) { return null; } } 


Et enfin, créons une classe VerticalSeekBar qui sera une version personnalisée d'un SeekBar standard, la différence sera que notre SeekBar sera situé verticalement
VerticalSeekBar
 import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.SeekBar; public class VerticalSeekBar extends SeekBar { public VerticalSeekBar (Context context) { super(context); } public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public VerticalSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(h, w, oldh, oldw); } public synchronized void setProgress(int progress) { super.setProgress(progress); onSizeChanged(getWidth(), getHeight(), 0, 0); } protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); } protected void onDraw(Canvas c) { c.rotate(-90); c.translate(-getHeight(), 0); super.onDraw(c); } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_UP: setProgress(getMax() - (int) (getMax() * event.getY() / getHeight())); onSizeChanged(getWidth(), getHeight(), 0, 0); break; case MotionEvent.ACTION_CANCEL: break; } return true; } } 


Voici à quoi ressemblera le manifeste de l'application:
Manifeste
 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.bright"> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".BrightnessChekingService" android:enabled="true" android:exported="true"></service> </application> </manifest> 


C'est tout, un simple, mais fait avec un cadeau d'anniversaire d'âme à maman est prêt. Nous avons une telle chose:


Pour démonstration, j'ai supprimé la ligne qui définit la transparence, car dans ce mode la bande est presque invisible. Si vous le souhaitez, vous pouvez ajouter des boutons qui régulent la taille de la bande, sa position sur l'écran et la transparence.

Ici, vous pouvez prendre l'apkshnik. Si quelqu'un veut l'utiliser, j'aimerais avoir un retour, car je ne l'ai testé que sur le septième android. Et je tiens à exprimer ma profonde gratitude à ceux qui testent déjà l'application et signalent des bogues - vous m'aidez incroyablement. Je vous remercie!

Source: https://habr.com/ru/post/fr412967/


All Articles