Keep an android app up for demo
Revision | ced4bcfb6916ba349a1ae09217544eafa1f5a4eb (tree) |
---|---|
Time | 2014-01-29 04:53:27 |
Author | gull08 (HMML) <hmml3939@gmai...> |
Commiter | gull08 (HMML) |
Add intent recievers and use shared prefs to save settings.
@@ -12,6 +12,7 @@ | ||
12 | 12 | <uses-permission android:name="android.permission.GET_TASKS"/> |
13 | 13 | <uses-permission android:name="android.permission.WAKE_LOCK"/> |
14 | 14 | <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> |
15 | + <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> | |
15 | 16 | |
16 | 17 | <application |
17 | 18 | android:allowBackup="true" |
@@ -27,7 +28,18 @@ | ||
27 | 28 | <category android:name="android.intent.category.LAUNCHER" /> |
28 | 29 | </intent-filter> |
29 | 30 | </activity> |
30 | - <service android:name=".WatchService"/> | |
31 | + <service android:name="WatchService"/><receiver android:name="StartReceiver"> | |
32 | + <intent-filter> | |
33 | + <action android:name="android.intent.action.BOOT_COMPLETED" /> | |
34 | + <action android:name="android.intent.action.ACTION_POWER_CONNECTED" /> | |
35 | + </intent-filter> | |
36 | + </receiver> | |
37 | + | |
38 | + <receiver android:name="StopReceiver"> | |
39 | + <intent-filter> | |
40 | + <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/> | |
41 | + </intent-filter> | |
42 | + </receiver> | |
31 | 43 | </application> |
32 | 44 | |
33 | 45 | </manifest> |
@@ -39,15 +39,6 @@ | ||
39 | 39 | android:text="Enable" |
40 | 40 | android:textAppearance="?android:attr/textAppearanceLarge" /> |
41 | 41 | |
42 | - <TextView | |
43 | - android:id="@+id/textView2" | |
44 | - android:layout_width="wrap_content" | |
45 | - android:layout_height="wrap_content" | |
46 | - android:layout_alignParentLeft="true" | |
47 | - android:layout_below="@+id/radioGroupEnabled" | |
48 | - android:text="Watch Interval" | |
49 | - android:textAppearance="?android:attr/textAppearanceLarge" /> | |
50 | - | |
51 | 42 | <EditText |
52 | 43 | android:id="@+id/text_interval" |
53 | 44 | android:layout_width="wrap_content" |
@@ -70,4 +61,33 @@ | ||
70 | 61 | android:layout_toRightOf="@+id/text_interval" |
71 | 62 | android:text="sec" /> |
72 | 63 | |
64 | + <TextView | |
65 | + android:id="@+id/textView4" | |
66 | + android:layout_width="wrap_content" | |
67 | + android:layout_height="wrap_content" | |
68 | + android:layout_alignLeft="@+id/text_interval" | |
69 | + android:layout_below="@+id/text_interval" | |
70 | + android:layout_marginTop="16dp" | |
71 | + android:text="Trigger open URL" | |
72 | + android:textAppearance="?android:attr/textAppearanceLarge" /> | |
73 | + | |
74 | + <TextView | |
75 | + android:id="@+id/textView2" | |
76 | + android:layout_width="wrap_content" | |
77 | + android:layout_height="wrap_content" | |
78 | + android:layout_alignLeft="@+id/radioGroupEnabled" | |
79 | + android:layout_below="@+id/radioGroupEnabled" | |
80 | + android:layout_marginTop="16dp" | |
81 | + android:text="Watch Interval" | |
82 | + android:textAppearance="?android:attr/textAppearanceLarge" /> | |
83 | + | |
84 | + <EditText | |
85 | + android:id="@+id/text_open" | |
86 | + android:layout_width="wrap_content" | |
87 | + android:layout_height="wrap_content" | |
88 | + android:layout_alignLeft="@+id/textView4" | |
89 | + android:layout_alignParentRight="true" | |
90 | + android:layout_below="@+id/textView4" | |
91 | + android:ems="10" /> | |
92 | + | |
73 | 93 | </RelativeLayout> |
\ No newline at end of file |
@@ -9,6 +9,10 @@ import android.app.PendingIntent; | ||
9 | 9 | import android.content.Context; |
10 | 10 | import android.content.Intent; |
11 | 11 | import android.content.SharedPreferences; |
12 | +import android.content.SharedPreferences.Editor; | |
13 | +import android.sax.TextElementListener; | |
14 | +import android.text.Editable; | |
15 | +import android.text.TextWatcher; | |
12 | 16 | import android.util.Log; |
13 | 17 | import android.view.Menu; |
14 | 18 | import android.widget.EditText; |
@@ -17,7 +21,8 @@ import android.widget.RadioGroup; | ||
17 | 21 | import android.widget.RadioGroup.OnCheckedChangeListener; |
18 | 22 | |
19 | 23 | public class MainActivity extends Activity { |
20 | - private SharedPreferences prefs; | |
24 | + protected SharedPreferences prefs; | |
25 | + protected WatchService watcher; | |
21 | 26 | |
22 | 27 | @Override |
23 | 28 | protected void onCreate(Bundle savedInstanceState) { |
@@ -25,6 +30,7 @@ public class MainActivity extends Activity { | ||
25 | 30 | setContentView(R.layout.activity_main); |
26 | 31 | |
27 | 32 | this.prefs = PreferenceManager.getDefaultSharedPreferences(this); |
33 | + this.watcher = new WatchService(); | |
28 | 34 | |
29 | 35 | RadioGroup enable_raidos = (RadioGroup) findViewById(R.id.radioGroupEnabled); |
30 | 36 | enable_raidos.setOnCheckedChangeListener(new OnCheckedChangeListener() { |
@@ -40,6 +46,51 @@ public class MainActivity extends Activity { | ||
40 | 46 | |
41 | 47 | } |
42 | 48 | }); |
49 | + | |
50 | + EditText interval = (EditText) findViewById(R.id.text_interval); | |
51 | + interval.setText(String.valueOf(prefs.getInt("interval", WatchService.DEFAULT_INTERVAL))); | |
52 | + interval.addTextChangedListener(new TextWatcher() { | |
53 | + | |
54 | + @Override | |
55 | + public void onTextChanged(CharSequence s, int start, int before, int count) { | |
56 | + return; | |
57 | + } | |
58 | + | |
59 | + @Override | |
60 | + public void beforeTextChanged(CharSequence s, int start, int count, int after) { | |
61 | + return; | |
62 | + } | |
63 | + | |
64 | + @Override | |
65 | + public void afterTextChanged(Editable s) { | |
66 | + Editor peditor = MainActivity.this.prefs.edit(); | |
67 | + peditor.putInt("interval", MainActivity.this.getInterval()/1000); | |
68 | + peditor.commit(); | |
69 | + } | |
70 | + }); | |
71 | + | |
72 | + EditText open = (EditText) findViewById(R.id.text_open); | |
73 | + open.setText(prefs.getString("open", WatchService.DEFAULT_OPEN)); | |
74 | + open.addTextChangedListener(new TextWatcher() { | |
75 | + | |
76 | + @Override | |
77 | + public void onTextChanged(CharSequence s, int start, int before, int count) { | |
78 | + return; | |
79 | + } | |
80 | + | |
81 | + @Override | |
82 | + public void beforeTextChanged(CharSequence s, int start, int count, int after) { | |
83 | + return; | |
84 | + | |
85 | + } | |
86 | + | |
87 | + @Override | |
88 | + public void afterTextChanged(Editable s) { | |
89 | + Editor peditor = MainActivity.this.prefs.edit(); | |
90 | + peditor.putString("open", s.toString()); | |
91 | + peditor.commit(); | |
92 | + } | |
93 | + }); | |
43 | 94 | } |
44 | 95 | |
45 | 96 | @Override |
@@ -48,10 +99,10 @@ public class MainActivity extends Activity { | ||
48 | 99 | |
49 | 100 | RadioButton radio_enabled = (RadioButton) findViewById(R.id.radio_enabled); |
50 | 101 | RadioButton radio_disabled = (RadioButton) findViewById(R.id.radio_disabled); |
51 | - if (this.getPendingIntent() == null) { | |
52 | - radio_disabled.setChecked(true); | |
53 | - } else { | |
102 | + if (this.prefs.getBoolean("enabled", false)) { | |
54 | 103 | radio_enabled.setChecked(true); |
104 | + } else { | |
105 | + radio_disabled.setChecked(true); | |
55 | 106 | } |
56 | 107 | } |
57 | 108 |
@@ -62,37 +113,16 @@ public class MainActivity extends Activity { | ||
62 | 113 | return true; |
63 | 114 | } |
64 | 115 | |
65 | - public PendingIntent getPendingIntent() { | |
66 | - return this.getPendingIntent(false); | |
67 | - } | |
68 | - | |
69 | - public PendingIntent getPendingIntent(boolean create) { | |
70 | - int flag; | |
71 | - if (create) { | |
72 | - flag = PendingIntent.FLAG_UPDATE_CURRENT; | |
73 | - } else { | |
74 | - flag = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_NO_CREATE; | |
75 | - } | |
76 | - Context context = getBaseContext(); | |
77 | - Intent intent = new Intent(context, WatchService.class); | |
78 | - intent.putExtra("open", this.getOpenTarget()); | |
79 | - intent.putExtra("watch", this.getWatchTarget()); | |
80 | - return PendingIntent.getService(context, 0, intent, flag); | |
81 | - } | |
82 | - | |
83 | 116 | public void cancelSchedule() { |
84 | - PendingIntent intent = this.getPendingIntent(); | |
85 | - if (intent == null) return; | |
86 | - Log.d(this.getClass().getSimpleName(), "Disable watch schedule"); | |
87 | - AlarmManager manager = (AlarmManager) getBaseContext().getSystemService(ALARM_SERVICE); | |
88 | - manager.cancel(intent); | |
89 | - intent.cancel(); | |
117 | + watcher.cancelSchedule(getApplicationContext()); | |
90 | 118 | } |
91 | 119 | |
92 | 120 | public void schedule() { |
93 | 121 | Log.d(this.getClass().getSimpleName(), "Enable watch schedule"); |
94 | - AlarmManager manager = (AlarmManager) getBaseContext().getSystemService(ALARM_SERVICE); | |
95 | - manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), this.getInterval(), this.getPendingIntent(true)); | |
122 | + Editor peditor = this.prefs.edit(); | |
123 | + peditor.putBoolean("enabled", true); | |
124 | + peditor.commit(); | |
125 | + watcher.schedule(getApplicationContext()); | |
96 | 126 | } |
97 | 127 | |
98 | 128 | public int getInterval() { |
@@ -103,16 +133,9 @@ public class MainActivity extends Activity { | ||
103 | 133 | sec = 0; |
104 | 134 | } |
105 | 135 | if (sec < 1) |
106 | - sec = 30; | |
136 | + sec = WatchService.DEFAULT_INTERVAL; | |
107 | 137 | Log.d(this.getClass().getSimpleName(), "getInterval: "+String.valueOf(sec)); |
108 | 138 | return sec * 1000; |
109 | 139 | } |
110 | 140 | |
111 | - public String getWatchTarget() { | |
112 | - return this.prefs.getString("watch", "com.mxtech.videoplayer.pro"); | |
113 | - } | |
114 | - | |
115 | - public String getOpenTarget() { | |
116 | - return this.prefs.getString("open", "file:///sdcard/test/test.mp4"); | |
117 | - } | |
118 | 141 | } |
@@ -0,0 +1,14 @@ | ||
1 | +package jp.nekoteki.android.demowatcher; | |
2 | + | |
3 | +import android.content.BroadcastReceiver; | |
4 | +import android.content.Context; | |
5 | +import android.content.Intent; | |
6 | +import android.widget.Toast; | |
7 | + | |
8 | +public class StartReceiver extends BroadcastReceiver { | |
9 | + | |
10 | + @Override | |
11 | + public void onReceive(Context context, Intent intent) { | |
12 | + new WatchService().schedule(context); | |
13 | + } | |
14 | +} |
@@ -0,0 +1,14 @@ | ||
1 | +package jp.nekoteki.android.demowatcher; | |
2 | + | |
3 | +import android.content.BroadcastReceiver; | |
4 | +import android.content.Context; | |
5 | +import android.content.Intent; | |
6 | +import android.widget.Toast; | |
7 | + | |
8 | +public class StopReceiver extends BroadcastReceiver { | |
9 | + | |
10 | + @Override | |
11 | + public void onReceive(Context context, Intent intent) { | |
12 | + new WatchService().cancelSchedule(context); | |
13 | + } | |
14 | +} |
@@ -2,22 +2,31 @@ package jp.nekoteki.android.demowatcher; | ||
2 | 2 | |
3 | 3 | import android.app.ActivityManager; |
4 | 4 | import android.app.ActivityManager.RunningAppProcessInfo; |
5 | +import android.app.AlarmManager; | |
5 | 6 | import android.app.IntentService; |
6 | 7 | import android.app.KeyguardManager; |
8 | +import android.app.PendingIntent; | |
7 | 9 | import android.app.KeyguardManager.KeyguardLock; |
8 | 10 | import android.content.ComponentName; |
9 | 11 | import android.content.Context; |
10 | 12 | import android.content.Intent; |
13 | +import android.content.SharedPreferences; | |
14 | +import android.content.SharedPreferences.Editor; | |
11 | 15 | import android.net.Uri; |
12 | 16 | import android.os.PowerManager; |
17 | +import android.preference.PreferenceManager; | |
13 | 18 | import android.provider.BaseColumns; |
14 | 19 | import android.util.Log; |
15 | 20 | import android.view.Window; |
16 | 21 | import android.view.WindowManager; |
17 | 22 | import android.webkit.MimeTypeMap; |
23 | +import android.widget.Toast; | |
18 | 24 | |
19 | 25 | public class WatchService extends IntentService { |
20 | 26 | final static String NAME = "DemoWatchService"; |
27 | + final public static String DEFAULT_WATCH = "com.mxtech.videoplayer.pro"; | |
28 | + final public static String DEFAULT_OPEN = "file:///sdcard/test/test.mp4"; | |
29 | + final public static int DEFAULT_INTERVAL = 30; | |
21 | 30 | |
22 | 31 | public WatchService() { |
23 | 32 | super(NAME); |
@@ -27,31 +36,106 @@ public class WatchService extends IntentService { | ||
27 | 36 | super(name); |
28 | 37 | } |
29 | 38 | |
39 | + public PendingIntent getPendingIntent(Context context) { | |
40 | + return this.getPendingIntent(context, false); | |
41 | + } | |
42 | + | |
43 | + public PendingIntent getPendingIntent(Context context, boolean create) { | |
44 | + int flag; | |
45 | + if (create) { | |
46 | + flag = PendingIntent.FLAG_UPDATE_CURRENT; | |
47 | + } else { | |
48 | + flag = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_NO_CREATE; | |
49 | + } | |
50 | + Intent intent = new Intent(context, WatchService.class); | |
51 | + intent.putExtra("open", this.getOpenTarget(context)); | |
52 | + intent.putExtra("watch", this.getWatchTarget(context)); | |
53 | + return PendingIntent.getService(context, 0, intent, flag); | |
54 | + } | |
55 | + | |
56 | + public SharedPreferences getPrefs(Context c) { | |
57 | + return PreferenceManager.getDefaultSharedPreferences(c); | |
58 | + } | |
59 | + | |
60 | + public String getWatchTarget(Context c) { | |
61 | + return getPrefs(c).getString("watch", DEFAULT_WATCH); | |
62 | + } | |
63 | + | |
64 | + public String getOpenTarget(Context c) { | |
65 | + return getPrefs(c).getString("open", DEFAULT_OPEN); | |
66 | + } | |
67 | + | |
68 | + public int getInterval(Context c) { | |
69 | + return getPrefs(c).getInt("interval", DEFAULT_INTERVAL); | |
70 | + } | |
71 | + | |
72 | + | |
73 | + public void cancelSchedule(Context context) { | |
74 | + Editor peditor = getPrefs(context).edit(); | |
75 | + peditor.putBoolean("enabled", false); | |
76 | + peditor.commit(); | |
77 | + | |
78 | + PendingIntent intent = this.getPendingIntent(context); | |
79 | + if (intent == null) return; | |
80 | + Log.d(this.getClass().getSimpleName(), "Disable watch schedule"); | |
81 | + AlarmManager manager = (AlarmManager) context.getSystemService(ALARM_SERVICE); | |
82 | + manager.cancel(intent); | |
83 | + intent.cancel(); | |
84 | + | |
85 | + killWatchTarget(context); | |
86 | + } | |
87 | + | |
88 | + public void schedule(Context context) { | |
89 | + Editor peditor = getPrefs(context).edit(); | |
90 | + peditor.putBoolean("enabled", true); | |
91 | + peditor.commit(); | |
92 | + | |
93 | + AlarmManager manager = (AlarmManager) context.getSystemService(ALARM_SERVICE); | |
94 | + manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, | |
95 | + System.currentTimeMillis(), this.getInterval(context) * 1000, | |
96 | + this.getPendingIntent(context, true)); | |
97 | + | |
98 | + } | |
99 | + | |
30 | 100 | @Override |
31 | 101 | protected void onHandleIntent(Intent intent) { |
32 | 102 | Log.d(NAME, "Run watch handle!"); |
33 | 103 | |
34 | 104 | this.forceWake(); |
35 | - | |
36 | - if (this.checkTopActivity(intent.getStringExtra("watch"))) | |
105 | + | |
106 | + if (checkTopActivity(intent.getStringExtra("watch"))) | |
37 | 107 | return; |
38 | - | |
39 | - String url = intent.getStringExtra("open"); | |
40 | - Intent openintent = new Intent(Intent.ACTION_VIEW); | |
41 | -// String extention = MimeTypeMap.getFileExtensionFromUrl(url); | |
42 | -// String mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extention); | |
43 | - openintent.setData(Uri.parse(url)); | |
44 | -// openintent.setType(mimetype); | |
45 | - openintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); | |
46 | - | |
47 | - Log.d(NAME, "Sending view intent with "+url); | |
48 | - startActivity(openintent); | |
49 | 108 | |
50 | - // TODO: unlock support. | |
109 | + String url = intent.getStringExtra("open"); | |
110 | + Intent openintent = new Intent(Intent.ACTION_VIEW); | |
111 | + openintent.setData(Uri.parse(url)); | |
112 | + openintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); | |
113 | + | |
114 | + Log.d(NAME, "Sending view intent with "+url); | |
115 | + | |
116 | + try { | |
117 | + startActivity(openintent); | |
118 | + } catch (Exception e) { | |
119 | + Log.d(NAME, "Faild to Start: "+e.getMessage()); | |
120 | + } | |
121 | + | |
122 | + // TODO: unlock support. | |
123 | + } | |
124 | + | |
125 | + public void killWatchTarget(Context context) { | |
126 | + ActivityManager am = (ActivityManager)context.getSystemService(ACTIVITY_SERVICE); | |
127 | + String watch = getWatchTarget(context); | |
128 | + Log.d(NAME, "Killing "+watch); | |
129 | + am.killBackgroundProcesses(watch); | |
130 | + for (RunningAppProcessInfo pi : am.getRunningAppProcesses()) { | |
131 | + if (!watch.equals(pi.processName)) | |
132 | + continue; | |
133 | + Log.d(NAME, "Kill pid="+String.valueOf(pi.pid)); | |
134 | + android.os.Process.killProcess(pi.pid); | |
135 | + } | |
51 | 136 | } |
52 | 137 | |
53 | 138 | public boolean checkTopActivity(String watch) { |
54 | - | |
55 | 139 | ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE); |
56 | 140 | String front = am.getRunningTasks(1).get(0).topActivity.getPackageName(); |
57 | 141 | Log.d(NAME, "Current top task: "+front); |
@@ -59,13 +143,6 @@ public class WatchService extends IntentService { | ||
59 | 143 | Log.d(NAME, watch+" is running on top."); |
60 | 144 | return true; |
61 | 145 | } |
62 | - /* | |
63 | - for (RunningAppProcessInfo pi : am.getRunningAppProcesses()) { | |
64 | - Log.d(NAME, "Proc: "+pi.processName); | |
65 | - if (watch.equals(pi.processName)) | |
66 | - return; | |
67 | - } | |
68 | - */ | |
69 | 146 | |
70 | 147 | Log.i(NAME, "Watch target '"+watch+"' is not top activitiy."); |
71 | 148 | return false; |