編輯:關於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; } }
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; //定義一個存放圖片路徑的集合 ArrayListSettingActivity.java(設置菜單界面類)picPaths=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; } }
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工具類:
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); } } }
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配置清單:
目前,市場上很多Android手機軟件都具有清理SD卡緩存的功能,比如360,金山等等。那麼這些軟件是如何實現清理sd卡緩存數據功能的呢?下面,我就給大家演示下,這些功能
當Android系統捕獲到用戶的各種輸入事件後,如何准確地傳遞給真正需要這個事件的控件呢?Android給我們提供了一整套完善的事件傳遞、處理機制,來幫助開發者完成准確的
實現刮刮卡我們可以Get到哪些技能?* 圓形圓角圖片的實現原理* 雙緩沖技術繪圖* Bitmap獲取像素值數據* 獲取繪制文本的長寬* 自定義View的掌握* 獲取屏幕密
Android Eclipse導入Android Sample詳解1.new--->project--->Android--->Android Samp