zoukankan      html  css  js  c++  java
  • 控制音量大小widget

    由于手机音量按键非常悲剧的掉了。无法控制手机音量大小。使用起来非常不方便。所以决定写一个小widget放在桌面能够随时控制音量吧。也算是解决一点便利问题。

    1.一个简单的widget

    由于我的需求非常easy不须要写一个程序再提供一个widget。所以直接一个AppWidgetProvider就好也就不须要AppWidgetHost 

    先在AndroidManifest里面增加一个receiver

    <receiver android:name="WidgetProvider">
                <intent-filter>
                    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.appwidget.action.ACTION_APPWIDGET_ENABLED" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.appwidget.action.ACTION_APPWIDGET_DELETED" />
                </intent-filter>
                <meta-data android:name="android.appwidget.provider"
                    android:resource="@xml/widget_provider"/>
            </receiver>

    WidgetProvider是继承AppWidgetProvider的一个类,用来widget的详细响应实现。

    里面的<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_provider"/>说明此receiver是widget,widget提供者的详细定义在xml文件widget_provider中。里面定义了widget的宽高,更新时间以及布局文件等。

    widget_provider文件

    <?

    xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="70dp" android:minHeight="140dp" android:updatePeriodMillis="86400000" android:initialLayout="@layout/widget"> </appwidget-provider>

    以及layout文件widget。简单的两个按钮,音量加减。

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <Button
            android:id="@+id/button_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:textSize="14pt"
            android:text="+" />
    
        <Button
            android:id="@+id/button_reduce"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/button_add"
            android:layout_below="@+id/button_add"
            android:textSize="14pt"
            android:text="-" />
    
    </RelativeLayout>
    接下来就是WidgetProvider类了,它继承了AppWidgetProvider。

    其实一个AppWidgetProvider是一个BroadcastReceiver,仅仅是要实现几个函数:
    1 public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
    2 public void onDeleted(Context context, int[] appWidgetIds)
    3 public void onEnabled(Context context)
    4 public void onDisabled(Context context) 
    这几个函数用来响应AppWidget发出的对应的广播消息。他们的顺序是onEnabled ----> onUpdate ---> onDeleted ---> onDisabled。当你把widget放入桌面时,会运行onEnabled ----> onUpdate。然后到了定义的updatePeriodMillis时间时会运行一次Update,onUpdate方法会被调用,假设你从桌面删除widget则运行onDeleted ---> onDisabled方法。

    在widget中对两个音量按钮设置监听器

    public void onUpdate(Context context, int[] appIds) {
    		System.out.println("update");
    		
    		RemoteViews rv = new RemoteViews(context.getApplicationContext().getPackageName(), R.layout.activity_main);  
            PendingIntent add = PendingIntent.getBroadcast(context, 0,  
            		new Intent("CLICK_ACTION_ADD") , 0);
            rv.setOnClickPendingIntent(R.id.button_add, add);
            PendingIntent reduce = PendingIntent.getBroadcast(context, 0, new Intent("CLICK_ACTION_REDUCE"), 0);
            rv.setOnClickPendingIntent(R.id.button_reduce, reduce);
            
            AppWidgetManager appWidgetManger = AppWidgetManager
    				.getInstance(context);
    		appWidgetManger.updateAppWidget(appIds, rv);
    	}
    这样按钮在点击的时候会发送CLICK_ACTION_ADD或者CLICK_ACTION_REDUCE广播,因此须要在AndroidManifest里面的receiver再增加两个intent-filter
    <span style="white-space:pre">	</span>    <intent-filter>
                    <action android:name="CLICK_ACTION_ADD"/>
                </intent-filter>
                <intent-filter>
                    <action android:name="CLICK_ACTION_REDUCE"/>
                </intent-filter>
    声音的控制用AudioManager来实现,其adjustVolume方法能够控制最相关音量依照一个方向改变,增大或减小

    AudioManager AM;
    
    AM = (AudioManager)context.getSystemService("audio");
    
    AM.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI|AudioManager.FLAG_PLAY_SOUND);

    后面的flag參数能够控制是否显示音量UI。以及更改时是否播放声音。

    完整的WidgetProvider类

    package com.frank.widgettest;
    
    import android.app.PendingIntent;
    import android.appwidget.AppWidgetManager;
    import android.appwidget.AppWidgetProvider;
    import android.content.Context;
    import android.content.Intent;
    import android.media.AudioManager;
    import android.widget.RemoteViews;
    
    public class WidgetProvider extends AppWidgetProvider{
    
    	AudioManager AM;
    	
    	@Override
    	public void onEnabled(Context context) {
    		System.out.println("onEnabled");
    		super.onEnabled(context);
    	}
    	
    	@Override
    	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
    			int[] appWidgetIds) {
    		System.out.println("update");
    		RemoteViews rv = new RemoteViews(context.getApplicationContext().getPackageName(), R.layout.widget);  
            PendingIntent add = PendingIntent.getBroadcast(context, 0,  
            		new Intent("CLICK_ACTION_ADD") , 0);
            rv.setOnClickPendingIntent(R.id.button_add, add);
            PendingIntent reduce = PendingIntent.getBroadcast(context, 0, new Intent("CLICK_ACTION_REDUCE"), 0);
            rv.setOnClickPendingIntent(R.id.button_reduce, reduce);
            
            AppWidgetManager appWidgetManger = AppWidgetManager
    				.getInstance(context);
    		appWidgetManger.updateAppWidget(appWidgetIds, rv);
    		super.onUpdate(context, appWidgetManager, appWidgetIds);
    	}
    	
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		super.onReceive(context, intent);
    		if (intent.getAction().equals("CLICK_ACTION_ADD")) {
                if(AM == null)
        			AM = (AudioManager)context.getSystemService("audio");
                AM.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI|AudioManager.FLAG_PLAY_SOUND);
            }
            
            if(intent.getAction().equals("CLICK_ACTION_REDUCE")){
            	if(AM == null)
            		AM = (AudioManager)context.getSystemService("audio");
            	AM.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI|AudioManager.FLAG_PLAY_SOUND);
            }
    	}
    	
    	@Override
    	public void onDeleted(Context context, int[] appWidgetIds) {
    		System.out.println("deleted");
    		super.onDeleted(context, appWidgetIds);
    	}
    }

    2.BroadcastReceiver能够取代AppWidgetProvider

    其实第一次尝试的时候不知什么原因不能监听收到widget的onEnabled,onUpdate全部事件。一筹莫展时,看到Android API Guides里这样一段话


    既然如此,我干脆直接使用一个BroadcastReceiver来取代AppWidgetProvider试试看吧。

    结果没问题,各响应都能够收到音量控制正常。

    public class WidgetProvider extends BroadcastReceiver{
    	
    	AudioManager AM;
    	
    	public void onEnabled() {
    		System.out.println("onEnabled");
    	}
    	
    	public void onUpdate(Context context, int[] appIds) {
    		System.out.println("update");
    		
    		RemoteViews rv = new RemoteViews(context.getApplicationContext().getPackageName(), R.layout.activity_main);  
            PendingIntent add = PendingIntent.getBroadcast(context, 0,  
            		new Intent("CLICK_ACTION_ADD") , 0);
            rv.setOnClickPendingIntent(R.id.button_add, add);
            PendingIntent reduce = PendingIntent.getBroadcast(context, 0, new Intent("CLICK_ACTION_REDUCE"), 0);
            rv.setOnClickPendingIntent(R.id.button_reduce, reduce);
            
            AppWidgetManager appWidgetManger = AppWidgetManager
    				.getInstance(context);
    		appWidgetManger.updateAppWidget(appIds, rv);
    	}
    
    	@Override
    	public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("CLICK_ACTION_ADD")) {
                if(AM == null)
        			AM = (AudioManager)context.getSystemService("audio");
                AM.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI|AudioManager.FLAG_PLAY_SOUND);
            }
            
            if(intent.getAction().equals("CLICK_ACTION_REDUCE")){
            	if(AM == null)
            		AM = (AudioManager)context.getSystemService("audio");
            	AM.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI|AudioManager.FLAG_PLAY_SOUND);
            }
            
            if (intent.getAction().equals(AppWidgetManager.ACTION_APPWIDGET_ENABLED)){
            	onEnabled();
            }
            
            if (intent.getAction().equals(AppWidgetManager.ACTION_APPWIDGET_UPDATE)){
            	int[] appWidgetIds = intent.getExtras().getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
            	onUpdate(context, appWidgetIds);
            }
            
            if (intent.getAction().equals(AppWidgetManager.ACTION_APPWIDGET_DELETED)){
            	onDeleted();
            }
    	}
    	
    	public void onDeleted() {
    		System.out.println("deleted");
    	}
    由于逻辑方便定义的方法名也为AppWidgetProvider的方法名,也就是说用BroadcastReceiver能够做一个widget。

    后来我又新建一个项目使用AppWidgetProvider(第一个方案)也成功运行。


    转载请注明出处http://blog.csdn.net/franksun1991/article/details/26454043

查看全文
  • 相关阅读:
    【纯水题】POJ 1852 Ants
    【树形DP】BZOJ 1131 Sta
    【不知道怎么分类】HDU
    【树形DP】CF 1293E Xenon's Attack on the Gangs
    【贪心算法】CF Emergency Evacuation
    【思维】UVA 11300 Spreading the Wealth
    【树形DP】NOI2003 逃学的小孩
    【树形DP】BZOJ 3829 Farmcraft
    【树形DP】JSOI BZOJ4472 salesman
    【迷宫问题】CodeForces 1292A A NEKO's Maze Game
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10838721.html
  • Copyright © 2011-2022 走看看