Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之自動更換壁紙

Android開發之自動更換壁紙

編輯:關於Android編程

本程序主要實現了:

1.使用AssetManager將assets目錄中的文件復制到SD卡的指定位置

2.使用AlarmManager全局定時器,周期性的啟動指定組件切換壁紙

3.使用SharedPreferences,將用戶個性化的設置保存到手機(例如壁紙切換頻率)

4.使用自定義標題欄

5.使用了GestureDetector手勢檢測器,允許用戶滑動切屏

6.使用了overridePendingTransition,在切屏的時候有動畫效果

程序運行效果圖:

自動切換壁紙

程序代碼:

ChangeWallpaper.java:

package com.jph.changewallpaper;

import java.io.File;
import com.jph.util.Const;
import com.jph.util.CopyFolder;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ToggleButton;
/**
 * Describe:
*
幫你換壁紙 *
本程序主要實現了: *
1.使用AssetManager將assets目錄中的文件復制到SD卡的指定位置 *
2.使用AlarmManager全局定時器,周期性的啟動指定組件切換壁紙 *
3.使用SharedPreferences,將用戶個性化的設置保存到手機(例如壁紙切換頻率) *
4.使用自定義標題欄 *
5.使用了GestureDetector手勢檢測器,允許用戶滑動切屏 *
6.使用了overridePendingTransition,在切屏的時候有動畫效果 *
@author jph *
Date:2014.08.05 * * */ public class ChangeWallpaper extends Activity implements OnGestureListener{ //定義手勢檢測器實例 GestureDetector detector; // 定義AlarmManager對象 AlarmManager alarmManager; ToggleButton btnSwitch; ImageButton btnSetting; Intent intent; PendingIntent pi; //表示是不是第一次使用該應用 boolean isFirstUse; //是不開啟了自動切換壁紙 boolean isLaunch; //壁紙切換別的頻率 int frequency; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //設置自定義標題欄標志 ,該語句必須放在setContentView之前 requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.main); //設置自定義標題欄,改句必須放在setContentView之後 getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title); btnSwitch=(ToggleButton)findViewById(R.id.btnSwitch); btnSetting=(ImageButton)findViewById(R.id.btnSetting); btnSetting.setOnClickListener(listener); //初始化手勢檢測器 detector=new GestureDetector(this,this); // 指定啟動ChangeService組件 intent = new Intent(ChangeWallpaper.this,ChangeService.class); // 創建PendingIntent對象 pi=PendingIntent.getService(ChangeWallpaper.this, 0, intent, 0); //獲取系統的AlarmManager對象 alarmManager=(AlarmManager)getSystemService(Service.ALARM_SERVICE); //初始化程序配置 iniApp(); btnSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // TODO Auto-generated method stub isLaunch=isChecked; if (isChecked) { launchChangeService(); }else { // 取消對pi的調度 alarmManager.cancel(pi); } } }); } //啟動切換壁紙 protected void launchChangeService() { // TODO Auto-generated method stub // 設置每隔5秒執行pi代表的組件一次 alarmManager.setRepeating(AlarmManager.RTC_WAKEUP , 0, frequency, pi); Toast.makeText(ChangeWallpaper.this, "壁紙定時更換啟動成功啦", Toast.LENGTH_SHORT).show(); } OnClickListener listener=new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.btnSetting: showSetting(); break; default: break; } } }; //初始化應用,如果第一次使用,則將asset下的壁紙拷貝到SD卡上 private void iniApp() { // TODO Auto-generated method stub //獲取系統的SharedPreferences對象 SharedPreferences preferences=getSharedPreferences("config", MODE_PRIVATE); //獲取配置文件中的isFirstUse isFirstUse=preferences.getBoolean("isFirstUse", true); //獲取配置文件中的frequency切換頻率,默認五秒 frequency=preferences.getInt(Const.SETING_FREQUENCY_Str, 5000); if (isFirstUse) {//如果第一次使用,則將asset下的壁紙拷貝到SD卡上 //如果手機插入了SD卡,且程序有讀取SD卡的權限 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //獲取手機SD卡的目錄 File sdCardDir=Environment.getExternalStorageDirectory(); String path=null; try { path=sdCardDir.getCanonicalPath()+File.separator+"wallpaper"; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } CopyFolder cf=new CopyFolder(ChangeWallpaper.this, "wpics", path); cf.start();//啟動線程 } } } //顯示程序設置界面 protected void showSetting() { // TODO Auto-generated method stub //啟動設置界面 Intent intent=new Intent(ChangeWallpaper.this, SettingActivity.class); startActivityForResult(intent,Const.REQUESTCODE_FOR_SETTING); //設置切換動畫,從右邊進入,左邊退出 overridePendingTransition(R.anim.right_in, R.anim.left_out); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub switch (requestCode) { case Const.REQUESTCODE_FOR_SETTING://如果從設置界面返回 if (isLaunch) {//如果已經啟動了自動且換壁紙 //獲取配置信息 iniApp(); launchChangeService(); } break; default: break; } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub switch (keyCode) { case KeyEvent.KEYCODE_MENU://當按下菜單鍵跳轉到設置界面 showSetting(); break; default: break; } return super.onKeyDown(keyCode, event); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.change_wallpaper, menu); return true; } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub //將觸碰事件交給GestureDetector處理 return detector.onTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub //如果想右滑動的距離大於50mm if (e1.getX()-e2.getX()>50) { showSetting(); } return false; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } }

ChangeService.java(ChangeService切換壁紙類):

package com.jph.changewallpaper;

import java.io.File;
import java.util.ArrayList;
import com.jph.util.CopyFolder;
import android.app.Service;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.IBinder;
import android.widget.Toast;
/**
 * Describe:
*
ChangeService切換壁紙類 *
獲取SD卡的指定指定目錄下的圖片 *
使用WallpaperManager來更換當前壁紙 *
@author jph *
Date:2014.08.05 * * */ public class ChangeService extends Service { //定義一個存放圖片名的數組 String []fileNames; //定義一個存放圖片路徑的集合 ArrayListpicPaths=new ArrayList(); // 定義系統的壁紙管理服務 WallpaperManager wManager; // 定義當前所顯示的壁紙 int current = 0,flag=0; //創建一個CopyFolder類的對象 CopyFolder cf=null; public ChangeService() { // TODO Auto-generated constructor stub super(); } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); //初始化WallpaperManager wManager = WallpaperManager.getInstance(this); if (picPaths.isEmpty()) {//如果picPaths中還沒有照片 getPicPath(); } flag++; Toast.makeText(ChangeService.this, "flag:"+flag,Toast.LENGTH_SHORT).show(); System.out.println("=========================="); System.out.println( "flag:"+flag); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub System.out.println("=========================="); System.out.println( "onStartCommand:"+flag); // 如果到了最後一張,系統重新開始 if(current >picPaths.size()) current = 0; try { //將指定路徑的圖片轉換成bitmap Bitmap bitmap=BitmapFactory.decodeFile(picPaths.get(current++).toString()); // 改變壁紙 wManager.setBitmap(bitmap); } catch (Exception e) { e.printStackTrace(); } return START_STICKY; } //從SD卡的根目錄下的wallpaper文件夾中讀出圖片路徑到picPaths集合中 public void getPicPath(){ System.out.println("=========================="); System.out.println( "getPicPath:"+flag); //如果手機插入了SD卡,且程序有讀取SD卡的權限 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //獲取手機SD卡的目錄 File sdCardDir=Environment.getExternalStorageDirectory(); String path=null; try { path=sdCardDir.getCanonicalPath()+File.separator+"wallpaper"; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } File file=new File(path); fileNames=file.list(); //如果wallpaper目錄不存在或為空則將assets目錄下的壁紙復制到wallpaper目錄下 if (fileNames==null||fileNames.length==0) { if (cf==null) { cf=new CopyFolder(ChangeService.this, "wpics", path); cf.start();//啟動線程 } } picPaths.clear();//清空集合中的數據 for (String picName:fileNames) { if (isPicture(picName)) { //將圖片的完整路徑添加到picPaths中 picPaths.add(path+File.separator+picName); } } } } /** * 判斷文件類型是否為圖片 * @param fileName String 用於判斷的文件名 * @return boolean * */ public boolean isPicture(String fileName) { //存放圖片格式的數組 String []limit=new String[]{".png",".jpg",".gif",".jpeg" + ".bmp",".PNG",".JPG",".GIF",".JPEG",".BMP"}; for (String str:limit) { if (fileName.endsWith(str)) {//如果指定文件名為以上其中一種格式則返回true return true; } } return false; } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } }
SettingActivity.java(設置菜單界面類)

package com.jph.changewallpaper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.jph.util.Const;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
/**
 * Describe:
*
設置菜單界面類 *
將用戶個性化的設置保存到SharedPreferences中 *
@author jph *
Date:2014.08.05 * */ public class SettingActivity extends Activity implements OnGestureListener{ private AlertDialog dialog; private AlertDialog.Builder builder; ListView list; //設置菜單標題 String []itemTitles; //設置菜單圖標 int []itemIcos; //壁紙切換頻率 String frequencyString; //定義手勢檢測器實例 GestureDetector detector; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.setting); //初始化手勢檢測器 detector=new GestureDetector(this,this); list=(ListView)findViewById(R.id.list); //初始化ListView initList(); } private void initList() { // TODO Auto-generated method stub //獲取itemTitles.xml中的選項標題和圖標 itemTitles=getResources().getStringArray(R.array.itemTitles); itemIcos=new int[]{R.drawable.setting_fre,R.drawable.setting_fs ,R.drawable.setting_redefault,R.drawable.setting_abuot}; List>listItems=new ArrayList>(); for (int i = 0; i < itemTitles.length; i++) { MaplistItem=new HashMap(); listItem.put("imgItemIco", itemIcos[i]); listItem.put("txtItemTitle", itemTitles[i]); listItems.add(listItem); } SimpleAdapter adapter=new SimpleAdapter(SettingActivity.this,listItems, R.layout.line, new String[]{"imgItemIco","txtItemTitle"}, new int[]{R.id.imgItemIco,R.id.txtItemTitle}); list.setAdapter(adapter); list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { // TODO Auto-generated method stub switch (position) { case 0: //設置壁紙切換的屏幕 setFrequency(); break; case 1: displayPattern(); break; case 2: break; case 3: about(); break; default: break; } } }); } //設置壁紙的顯示方式 protected void displayPattern() { // TODO Auto-generated method stub final String item[]=new String[]{"平鋪","拉伸","裁切","默認"}; DialogInterface.OnClickListener sListener=new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { frequencyString=item[which]; } }; builder=new AlertDialog.Builder(this); builder.setSingleChoiceItems(item, -1, sListener); dialog=builder.create(); dialog.setTitle("請設置壁紙顯示方式"); //創建按鍵監聽器 DialogInterface.OnClickListener listener=new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { if(which==DialogInterface.BUTTON_POSITIVE) {//按下確定 dialog.dismiss(); if (frequencyString.endsWith("秒")) { frequencyString=frequencyString.replace("秒", ""); //將String轉換成int int frequency=Integer.parseInt(frequencyString)*1000; alterConfig(Const.SETING_FREQUENCY,frequency); }else if (frequencyString.endsWith("分鐘")) { frequencyString=frequencyString.replace("分鐘", ""); //將String轉換成int int frequency=Integer.parseInt(frequencyString)*1000*60; alterConfig(Const.SETING_FREQUENCY,frequency); } }else if(which==DialogInterface.BUTTON_NEGATIVE){//按下取消 dialog.dismiss(); } } }; dialog.setButton(DialogInterface.BUTTON_POSITIVE, "確定",listener); dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消",listener); dialog.show(); } //關於 protected void about() { // TODO Auto-generated method stub LayoutInflater inflater=LayoutInflater.from(this); LinearLayout layout=(LinearLayout) inflater.inflate(R.layout.about, null); AlertDialog dialog=new AlertDialog.Builder(SettingActivity.this).create(); dialog.setTitle("關於"); dialog.setIcon(R.drawable.smile); dialog.setView(layout); dialog.show(); } //設置顯示頻率 protected void setFrequency() { // TODO Auto-generated method stub final String item[]=new String[]{"3秒","5秒","10秒","20秒","30秒","1分鐘","5分鐘","10分鐘"}; DialogInterface.OnClickListener sListener=new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { frequencyString=item[which]; } }; builder=new AlertDialog.Builder(this); builder.setSingleChoiceItems(item, -1, sListener); dialog=builder.create(); dialog.setTitle("請設置壁紙切換的頻率"); //創建按鍵監聽器 DialogInterface.OnClickListener listener=new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { if(which==DialogInterface.BUTTON_POSITIVE) {//按下確定 dialog.dismiss(); if (frequencyString.endsWith("秒")) { frequencyString=frequencyString.replace("秒", ""); //將String轉換成int int frequency=Integer.parseInt(frequencyString)*1000; alterConfig(Const.SETING_FREQUENCY,frequency); }else if (frequencyString.endsWith("分鐘")) { frequencyString=frequencyString.replace("分鐘", ""); //將String轉換成int int frequency=Integer.parseInt(frequencyString)*1000*60; alterConfig(Const.SETING_FREQUENCY,frequency); } }else if(which==DialogInterface.BUTTON_NEGATIVE){//按下取消 dialog.dismiss(); } } }; dialog.setButton(DialogInterface.BUTTON_POSITIVE, "確定",listener); dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消",listener); dialog.show(); } //修改配置文件 protected void alterConfig(int flag, int frequency) { // TODO Auto-generated method stub SharedPreferences preferences=getSharedPreferences("config", MODE_PRIVATE); //獲取SharedPreferences對應的Editor Editor editor=preferences.edit(); switch (flag) { case Const.SETING_FREQUENCY: editor.putInt(Const.SETING_FREQUENCY_Str, frequency); break; default: break; } editor.commit(); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub //將觸碰事件交給GestureDetector處理 return detector.onTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub //如果向左滑動距離大於50mm if (e2.getX()-e1.getX()>50) { Intent intent=getIntent(); setResult(Activity.RESULT_OK, intent); this.finish(); overridePendingTransition(R.anim.left_in, R.anim.right_out); } return false; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } }
工具類:

CopyFolder.java(復制assets中的文件到SD卡的指定位置)

package com.jph.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
/**
 * Describe:
*
從assets項目目錄中復制文件及目錄 *
本類啟用了一個新線程用於處理復制文件的耗時任務 *
當所有的復制完成或復制文件出錯時通知UI線程 *
@author JPH *
Date:2014.07.30 * */ public class CopyFolder extends Thread { //定義兩個常量用於表示復制文件成功的標識 public final static int COPY_FALSE=0x123,COPY_SUCCESS=0x456; String newPath,oldPath; Context context; public CopyFolder() { // TODO Auto-generated constructor stub } /** * 從assets目錄中復制整個文件夾內容 * @param context Context 使用CopyFiles類的Activity * @param oldPath String 原文件路徑 如:img * @param newPath String 復制後路徑 如:xx:/bb/cc */ public CopyFolder(Context context,String oldPath,String newPath) { this.context=context; this.oldPath=oldPath; this.newPath=newPath; } @Override public void run() { // TODO Auto-generated method stub copyFilesFassets(context,oldPath,newPath); SharedPreferences prference=context.getSharedPreferences("config", Context.MODE_PRIVATE); Editor editor=prference.edit(); editor.putBoolean("isFirstUse", false);//寫入使用標識 editor.commit();//最後不要忘記將存入的數據進行提交 // MainActivity.handler.sendEmptyMessage(COPY_SUCCESS); } /** * 從assets目錄中復制整個文件夾內容 * @param context Context 使用CopyFiles類的Activity * @param oldPath String 原文件路徑 如:/aa * @param newPath String 復制後路徑 如:xx:/bb/cc */ public void copyFilesFassets(Context context,String oldPath,String newPath) { try { String fileNames[] = context.getAssets().list(oldPath);//獲取assets目錄下的所有文件及目錄名 if (fileNames.length > 0) {//如果是目錄 File file = new File(newPath); file.mkdirs();//如果文件夾不存在,則遞歸 for (String fileName : fileNames) { copyFilesFassets(context,oldPath + "/" + fileName,newPath+"/"+fileName); } } else {//如果是文件 InputStream is = context.getAssets().open(oldPath); FileOutputStream fos = new FileOutputStream(new File(newPath)); byte[] buffer = new byte[1024]; int byteCount=0; while((byteCount=is.read(buffer))!=-1) {//循環從輸入流讀取 buffer字節 fos.write(buffer, 0, byteCount);//將讀取的輸入流寫入到輸出流 } fos.flush();//刷新緩沖區 is.close(); fos.close(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); //如果捕捉到錯誤則通知UI線程 // MainActivity.handler.sendEmptyMessage(COPY_FALSE); } } }

Const.java(常量類:提供程序中用到的主要常量)
package com.jph.util;
/**
 * Describe:
*
常量類 *
提供程序中用到的主要常量 *
@author jph *
Date:2014.08.05 * */ public class Const { //壁紙切換頻率標識 public final static int SETING_FREQUENCY=0x0001; public final static String SETING_FREQUENCY_Str="frequency"; //SettingActivity的請求碼 public final static int REQUESTCODE_FOR_SETTING=0x123; public Const() { // TODO Auto-generated constructor stub } }

AndroidManifest.xml配置清單:



    
    
	
	
	
	
	
    
        
            
                

                
            
        
        
        
        
    






  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved