1. 程式人生 > >Android小應用——監控螢幕使用時間

Android小應用——監控螢幕使用時間

idea來源

這個idea是蔡小亦童鞋提出來的。她說看到一條報道說有人看手機看太久眼睛怎麼怎麼了,所以想弄個應用來監控螢幕使用時間。答應幫她做已經答應很久了,剛好這周沒什麼事了,於是就開始做。從開始找資料到寫程式碼到美工到除錯完成,只花了1天時間,不錯不錯~因為我覺得這個做得很粗糙別人不可能會怎麼用,所以我就針對蔡小亦童鞋定製了流氓兔形象,哦哈哈是不是該感謝我~

預期目標

1、能記錄螢幕使用時間

2、每天凌晨清空資料,重新記錄

3、使用者可以自定義警戒線,當使用時間超過警戒線則在通知欄提醒。

主要程式碼

複製程式碼
 1 package com.legend;
 2 
 3 import java.text.SimpleDateFormat;
4 import java.util.Date; 5 6 import android.app.Activity; 7 import android.content.Context; 8 import android.content.Intent; 9 import android.content.SharedPreferences; 10 import android.os.Bundle; 11 import android.view.View; 12 import android.view.View.OnClickListener; 13 import android.widget.Button;
14 import android.widget.EditText; 15 import android.widget.TextView; 16 import android.widget.Toast; 17 18 /** 19 * 目前先實現最小功能,只提取出總的螢幕亮的時間 20 * 通過廣播來接收螢幕是否啟動這個事件 21 * @author 林培東 22 */ 23 public class MainActivity extends Activity 24 { 25 public TextView summary=null; 26 public TextView preset=null
; 27 public EditText set=null; 28 public Button submit=null; 29 30 @Override 31 public void onCreate(Bundle savedInstanceState) 32 { 33 super.onCreate(savedInstanceState); 34 setContentView(R.layout.main); 35 startService(new Intent("com.legend.SERVICE_DEMO"));//啟動服務 36 37 summary=(TextView)findViewById(R.id.summary); 38 preset=(TextView)findViewById(R.id.preset); 39 set=(EditText)findViewById(R.id.set); 40 submit=(Button)findViewById(R.id.submit); 41 42 //顯示已使用螢幕時間 43 SharedPreferences sp=getSharedPreferences("actm", Context.MODE_PRIVATE); 44 int sum=(int)sp.getLong("sum", 0L)/1000; 45 int hour=sum/3600; 46 int minute=(sum-hour*3600)/60; 47 int second=sum%60; 48 //格式化輸出日期 49 Date tmp=new Date(); 50 tmp.setHours(hour); 51 tmp.setMinutes(minute); 52 tmp.setSeconds(second); 53 SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss"); 54 String result=sdf.format(tmp); 55 summary.setText(result);//最終顯示 56 57 //顯示已儲存的設定 58 int limit=sp.getInt("limit", 24*60); 59 preset.setText(" 當前設定的預警分鐘數為"+Integer.toString(limit)); 60 61 //點選確定後重新設定 62 submit.setOnClickListener(new OnClickListener() 63 { 64 @Override 65 public void onClick(View v) 66 { 67 String tmp=set.getText().toString(); 68 if(tmp.equals("")) 69 Toast.makeText(MainActivity.this, "輸入不能為空!", Toast.LENGTH_SHORT).show(); 70 else 71 { 72 SharedPreferences sp=getSharedPreferences("actm", Context.MODE_PRIVATE); 73 SharedPreferences.Editor editor=sp.edit(); 74 editor.putInt("limit", Integer.parseInt(tmp)); 75 editor.commit(); 76 Toast.makeText(MainActivity.this, "已設定!", Toast.LENGTH_SHORT).show(); 77 preset.setText(" 當前設定的預警分鐘數為"+Integer.parseInt(tmp)); 78 } 79 } 80 }); 81 82 } 83 84 }
複製程式碼 複製程式碼
  1 package com.legend;
  2 
  3 import java.util.Date;
  4 import java.util.Timer;
  5 import java.util.TimerTask;
  6 
  7 import android.app.Notification;
  8 import android.app.NotificationManager;
  9 import android.app.PendingIntent;
 10 import android.app.Service;
 11 import android.content.BroadcastReceiver;
 12 import android.content.Context;
 13 import android.content.Intent;
 14 import android.content.IntentFilter;
 15 import android.content.SharedPreferences;
 16 import android.os.IBinder;
 17 
 18 /**
 19  * 建立一個服務,該服務主要用來接收廣播和建立定時器
 20  * @author 林培東
 21  */
 22 public class LocalService extends Service
 23 {
 24     private static final int NOTIFY_ID=1234;//通知的唯一識別符號
 25     
 26     //主要功能,廣播接收器
 27     private final BroadcastReceiver receiver=new BroadcastReceiver()
 28     {
 29         @Override
 30         public void onReceive(Context context, Intent intent)
 31         {
 32             SharedPreferences sp=getSharedPreferences("actm", Context.MODE_PRIVATE);
 33             SharedPreferences.Editor editor=sp.edit();
 34             
 35             if(intent.getAction().equals(Intent.ACTION_SCREEN_ON))
 36             {
 37                 //儲存螢幕啟動時的毫秒數                
 38                 editor.putLong("lasttime", new Date().getTime());
 39                 editor.commit();
 40                 
 41                 //根據需要看是否需要在通知欄提醒
 42                 int sum=(int)sp.getLong("sum", 0L)/1000;
 43                 int limit=sp.getInt("limit", 1440)*60;
 44                 if(limit<=sum)
 45                 {
 46                     final NotificationManager manager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);//獲取通知管理器
 47                     Notification notification=new Notification(R.drawable.ic_launcher,"警告",System.currentTimeMillis());//通知的時機
 48                     notification.flags = Notification.FLAG_AUTO_CANCEL;//點選一次通知就自動消失
 49                     PendingIntent pIntent=PendingIntent.getActivity(context,0,new Intent(context,MainActivity.class),0);//跳轉到主介面
 50                     notification.setLatestEventInfo(context,"警告","本日使用螢幕已超過預設,如需取消該警告請重新設定!!!",pIntent);//通知欄顯示內容
 51                     manager.notify(NOTIFY_ID, notification);//執行
 52                 }
 53             }
 54             else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
 55             {
 56                 //儲存螢幕總工作時間
 57                 long lasttime=sp.getLong("lasttime", new Date().getTime());
 58                 long sum=sp.getLong("sum", 0L);
 59                 sum+=new Date().getTime()-lasttime;
 60                 editor.putLong("sum", sum);
 61                 editor.commit();
 62             }
 63         }
 64     
 65     };
 66 
 67     @Override
 68     public void onCreate()
 69     {
 70         //新增過濾器並註冊
 71         final IntentFilter filter=new IntentFilter();
 72         filter.addAction(Intent.ACTION_SCREEN_ON);
 73         filter.addAction(Intent.ACTION_SCREEN_OFF);
 74         registerReceiver(receiver, filter);
 75                 
 76         //建立計劃任務
 77         TimerTask task=new TimerTask()
 78         {
 79             @Override
 80             public void run()
 81             {
 82                 //每天凌晨自動更新資料
 83                 SharedPreferences sp=getSharedPreferences("actm", Context.MODE_PRIVATE);
 84                 SharedPreferences.Editor editor=sp.edit();
 85                 editor.putLong("sum", 0L);
 86                 editor.commit();
 87                 
 88                 //取消通知欄通知
 89                 final NotificationManager manager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
 90                 manager.cancel(NOTIFY_ID);
 91             }           
 92         };
 93         Timer timer=new Timer(true);
 94         int hour=new Date().getHours();
 95         timer.schedule(task,(24-hour)*3600*1000, 24*3600*1000);
 96         //timer.schedule(task,180*1000, 180*1000);//測試用
 97         
 98         super.onCreate();
 99     }
100     
101     @Override
102     public IBinder onBind(Intent arg0)
103     {
104         return null;
105     }
106 
107 }
複製程式碼 複製程式碼
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="fill_parent"
 4     android:layout_height="fill_parent"
 5     android:background="@drawable/background"
 6     android:orientation="vertical" >
 7 
 8     <TextView
 9         android:layout_width="fill_parent"
10         android:layout_height="wrap_content"
11         android:textSize="25dp"
12         android:text="今天螢幕總共使用"
13         android:textColor="#000000"
14         android:gravity="center" />
15     
16     <TextView
17         android:id="@+id/summary"
18         android:layout_width="fill_parent"
19         android:layout_height="wrap_content"
20         android:textSize="50dp"
21         android:textColor="#000000"
22         android:gravity="center" />
23 
24     <TextView
25         android:id="@+id/preset"
26         android:layout_width="fill_parent"
27         android:layout_height="wrap_content"
28         android:textColor="#000000"/>
29     
30     <EditText
31         android:id="@+id/set"
32         android:layout_width="fill_parent"
33         android:layout_height="wrap_content"
34         android:hint="請輸入預警提醒分鐘數,如80"
35         android:inputType="number" />
36     
37     <Button
38         android:id="@+id/submit"
39         android:layout_width="fill_parent"
40         android:layout_height="wrap_content"
41         android:text="確定提交" />
42 
43 </LinearLayout>
複製程式碼 複製程式碼
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.legend"
 4     android:versionCode="1"
 5     android:versionName="1.0" >
 6 
 7     <uses-sdk android:minSdkVersion="4" />
 8 
 9     <application
10         android:icon="@drawable/ic_launcher"
11         android:label="@string/app_name" >
12         <activity
13             android:name=".MainActivity"
14             android:label="@string/app_name" >
15             <intent-filter>
16                 <action android:name="android.intent.action.MAIN" />
17 
18                 <category android:name="android.intent.category.LAUNCHER" />
19             </intent-filter>
20         </activity>
21         
22         <service android:name=".LocalService"> 
23             <intent-filter> 
24                 <action android:name="com.legend.SERVICE_DEMO" /> 
25                 <category android:name="android.intent.category.default" /> 
26             </intent-filter> 
27         </service>
28     </application>
29 
30 </manifest>
複製程式碼

專案分析

我遇到的第一個問題是:如何監控?

經過查資料,我發現當螢幕啟用或者鎖屏時,系統會分別傳送ACTION_SCREEN_ON和ACTION_SCREEN_OFF這兩個廣播。我們只需要在接收這兩個廣播時記錄時間就可以了。

注意:為了時程式退出後也能執行,必須使用Service。

注意:這兩個廣播是受保護的,只能在程式碼中註冊。

下面是在Service中註冊:

        //新增過濾器並註冊
        final IntentFilter filter=new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(receiver, filter);

在接收器receiver裡,定義了onReceive()來處理這些資料,主要功能都在裡面實現: