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

查看全文
  • 相关阅读:
    [转]托管DirectX,从MDX到SlimDX的转换
    [连载]Tutorial series: learning how to write a 3D soft engine from scratch in C#, TypeScript or JavaScript[英]
    关于VS2010 C#使用DirectX的问题[英]
    C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案
    C#常用控件缩写
    朴素贝叶斯
    scikit-learn 入门
    机器学习(6): 层次聚类 hierarchical clustering
    机器学习(5): K-means 算法
    机器学习(4): KNN 算法
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10838721.html
  • Copyright © 2011-2022 走看看