258 |
259 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/launcher/src/main/java/org/cosinus/launchertv/fragments/ApplicationFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Simple TV Launcher
3 | * Copyright 2017 Alexandre Del Bigio
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package org.cosinus.launchertv.fragments;
19 |
20 | import android.app.Activity;
21 | import android.content.BroadcastReceiver;
22 | import android.content.Context;
23 | import android.content.Intent;
24 | import android.content.IntentFilter;
25 | import android.content.SharedPreferences;
26 | import android.content.pm.PackageInfo;
27 | import android.content.pm.PackageManager;
28 | import android.os.BatteryManager;
29 | import android.os.Build;
30 | import android.os.Bundle;
31 | import android.os.Handler;
32 | import android.support.v4.app.Fragment;
33 | import android.text.TextUtils;
34 | import android.view.Gravity;
35 | import android.view.LayoutInflater;
36 | import android.view.View;
37 | import android.view.ViewGroup;
38 | import android.widget.ImageView;
39 | import android.widget.LinearLayout;
40 | import android.widget.TextView;
41 | import android.widget.Toast;
42 |
43 | import org.cosinus.launchertv.AppInfo;
44 | import org.cosinus.launchertv.R;
45 | import org.cosinus.launchertv.Setup;
46 | import org.cosinus.launchertv.Utils;
47 | import org.cosinus.launchertv.activities.ApplicationList;
48 | import org.cosinus.launchertv.activities.Preferences;
49 | import org.cosinus.launchertv.views.ApplicationView;
50 |
51 | import java.text.DateFormat;
52 | import java.util.Date;
53 |
54 | @SuppressWarnings("PointlessBooleanExpression")
55 | public class ApplicationFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener {
56 | public static final String TAG = "ApplicationFragment";
57 | private static final String PREFERENCES_NAME = "applications";
58 | private static final int REQUEST_CODE_APPLICATION_LIST = 0x1E;
59 | private static final int REQUEST_CODE_WALLPAPER = 0x1F;
60 | private static final int REQUEST_CODE_APPLICATION_START = 0x20;
61 | private static final int REQUEST_CODE_PREFERENCES = 0x21;
62 |
63 | private TextView mClock;
64 | private TextView mDate;
65 | private DateFormat mTimeFormat;
66 | private DateFormat mDateFormat;
67 | private TextView mBatteryLevel;
68 | private ImageView mBatteryIcon;
69 | private BroadcastReceiver mBatteryChangedReceiver = new BroadcastReceiver(){
70 | @Override
71 | public void onReceive(Context context, Intent intent) {
72 | final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
73 | mBatteryLevel.setText(
74 | String.format(getResources().getString(R.string.battery_level_text), level)
75 | );
76 | final int batteryIconId = intent.getIntExtra(BatteryManager.EXTRA_ICON_SMALL, 0);
77 | mBatteryIcon.setImageDrawable(getResources().getDrawable(batteryIconId));
78 | }
79 | };
80 | private boolean mBatteryChangedReceiverRegistered = false;
81 |
82 | private final Handler mHandler = new Handler();
83 | private final Runnable mTimerTick = new Runnable() {
84 | @Override
85 | public void run() {
86 | setClock();
87 | }
88 | };
89 |
90 | private int mGridX = 3;
91 | private int mGridY = 2;
92 | private LinearLayout mContainer;
93 | private ApplicationView[][] mApplications = null;
94 | private View mSettings;
95 | private View mGridView;
96 | private Setup mSetup;
97 |
98 |
99 | public ApplicationFragment() {
100 | // Required empty public constructor
101 | }
102 |
103 | public static ApplicationFragment newInstance() {
104 | return new ApplicationFragment();
105 | }
106 |
107 | @Override
108 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
109 | View view = inflater.inflate(R.layout.fragment_application, container, false);
110 |
111 | mSetup = new Setup(getContext());
112 | mContainer = (LinearLayout) view.findViewById(R.id.container);
113 | mSettings = view.findViewById(R.id.settings);
114 | mGridView = view.findViewById(R.id.application_grid);
115 | mClock = (TextView) view.findViewById(R.id.clock);
116 | mDate = (TextView) view.findViewById(R.id.date);
117 | final LinearLayout batteryLayout = (LinearLayout) view.findViewById(R.id.battery_layout);
118 | mBatteryLevel = (TextView) view.findViewById(R.id.battery_level);
119 | mBatteryIcon = (ImageView) view.findViewById(R.id.battery_icon);
120 |
121 | mTimeFormat = android.text.format.DateFormat.getTimeFormat(getActivity());
122 | mDateFormat = android.text.format.DateFormat.getLongDateFormat(getActivity());
123 |
124 | if (mSetup.keepScreenOn())
125 | mContainer.setKeepScreenOn(true);
126 |
127 | if (mSetup.showDate() == false)
128 | mDate.setVisibility(View.GONE);
129 |
130 | if (mSetup.showBattery()) {
131 | batteryLayout.setVisibility(View.VISIBLE);
132 | getActivity().registerReceiver(this.mBatteryChangedReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
133 | mBatteryChangedReceiverRegistered = true;
134 | } else {
135 | batteryLayout.setVisibility(View.INVISIBLE);
136 | if (mBatteryChangedReceiverRegistered) {
137 | getActivity().unregisterReceiver(this.mBatteryChangedReceiver);
138 | mBatteryChangedReceiverRegistered = false;
139 | }
140 | }
141 |
142 | mSettings.setOnClickListener(this);
143 | mGridView.setOnClickListener(this);
144 |
145 | createApplications();
146 |
147 | return view;
148 | }
149 |
150 | private void createApplications() {
151 | mContainer.removeAllViews();
152 |
153 | mGridX = mSetup.getGridX();
154 | mGridY = mSetup.getGridY();
155 |
156 | if (mGridX < 2)
157 | mGridX = 2;
158 | if (mGridY < 1)
159 | mGridY = 1;
160 |
161 | int marginX = Utils.getPixelFromDp(getContext(), mSetup.getMarginX());
162 | int marginY = Utils.getPixelFromDp(getContext(), mSetup.getMarginY());
163 |
164 | boolean showNames = mSetup.showNames();
165 |
166 | mApplications = new ApplicationView[mGridY][mGridX];
167 |
168 | int position = 0;
169 | for (int y = 0; y < mGridY; y++) {
170 | LinearLayout ll = new LinearLayout(getContext());
171 | ll.setOrientation(LinearLayout.HORIZONTAL);
172 | ll.setGravity(Gravity.CENTER_VERTICAL);
173 | ll.setFocusable(false);
174 | ll.setLayoutParams(new LinearLayout.LayoutParams(
175 | LinearLayout.LayoutParams.MATCH_PARENT, 0, 1
176 | ));
177 |
178 | for (int x = 0; x < mGridX; x++) {
179 | ApplicationView av = new ApplicationView(getContext());
180 | av.setOnClickListener(this);
181 | av.setOnLongClickListener(this);
182 | av.setOnMenuOnClickListener(new View.OnClickListener() {
183 | @Override
184 | public void onClick(View v) {
185 | onLongClick(v);
186 | }
187 | });
188 | av.setPosition(position++);
189 | av.showName(showNames);
190 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
191 | av.setId(0x00FFFFFF + position);
192 | } else {
193 | av.setId(View.generateViewId());
194 | }
195 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
196 | lp.setMargins(marginX, marginY, marginX, marginY);
197 | av.setLayoutParams(lp);
198 | ll.addView(av);
199 | mApplications[y][x] = av;
200 | }
201 | mContainer.addView(ll);
202 | }
203 |
204 | updateApplications();
205 | setApplicationOrder();
206 | }
207 |
208 | private void setApplicationOrder() {
209 | for (int y = 0; y < mGridY; y++) {
210 | for (int x = 0; x < mGridX; x++) {
211 | int upId = R.id.application_grid;
212 | int downId = R.id.settings;
213 | int leftId = R.id.application_grid;
214 | int rightId = R.id.settings;
215 |
216 | if (y > 0)
217 | upId = mApplications[y - 1][x].getId();
218 |
219 | if (y + 1 < mGridY)
220 | downId = mApplications[y + 1][x].getId();
221 |
222 | if (x > 0)
223 | leftId = mApplications[y][x - 1].getId();
224 | else if (y > 0)
225 | leftId = mApplications[y - 1][mGridX - 1].getId();
226 |
227 | if (x + 1 < mGridX)
228 | rightId = mApplications[y][x + 1].getId();
229 | else if (y + 1 < mGridY)
230 | rightId = mApplications[y + 1][0].getId();
231 |
232 | mApplications[y][x].setNextFocusLeftId(leftId);
233 | mApplications[y][x].setNextFocusRightId(rightId);
234 | mApplications[y][x].setNextFocusUpId(upId);
235 | mApplications[y][x].setNextFocusDownId(downId);
236 | }
237 | }
238 |
239 | mGridView.setNextFocusLeftId(R.id.settings);
240 | mGridView.setNextFocusRightId(mApplications[0][0].getId());
241 | mGridView.setNextFocusUpId(R.id.settings);
242 | mGridView.setNextFocusDownId(mApplications[0][0].getId());
243 |
244 | mSettings.setNextFocusLeftId(mApplications[mGridY - 1][mGridX - 1].getId());
245 | mSettings.setNextFocusRightId(R.id.application_grid);
246 | mSettings.setNextFocusUpId(mApplications[mGridY - 1][mGridX - 1].getId());
247 | mSettings.setNextFocusDownId(R.id.application_grid);
248 | }
249 |
250 |
251 | private void updateApplications() {
252 | PackageManager pm = getActivity().getPackageManager();
253 | SharedPreferences prefs = getActivity().getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
254 |
255 | for (int y = 0; y < mGridY; y++) {
256 | for (int x = 0; x < mGridX; x++) {
257 | ApplicationView app = mApplications[y][x];
258 | setApplication(pm, app, prefs.getString(app.getPreferenceKey(), null));
259 | }
260 | }
261 | }
262 |
263 |
264 | private void restartActivity() {
265 | if (mBatteryChangedReceiverRegistered) {
266 | getActivity().unregisterReceiver(mBatteryChangedReceiver);
267 | mBatteryChangedReceiverRegistered = false;
268 | }
269 | Intent intent = getActivity().getIntent();
270 | getActivity().finish();
271 | startActivity(intent);
272 | }
273 |
274 |
275 | private void writePreferences(int appNum, String packageName) {
276 | SharedPreferences prefs = getActivity().getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
277 | SharedPreferences.Editor editor = prefs.edit();
278 | String key = ApplicationView.getPreferenceKey(appNum);
279 |
280 | if (TextUtils.isEmpty(packageName))
281 | editor.remove(key);
282 | else
283 | editor.putString(key, packageName);
284 |
285 | editor.apply();
286 | }
287 |
288 | private void setApplication(PackageManager pm, ApplicationView app, String packageName) {
289 | try {
290 |
291 | if (TextUtils.isEmpty(packageName) == false) {
292 | PackageInfo pi = pm.getPackageInfo(packageName, 0);
293 | if (pi != null) {
294 | AppInfo appInfo = new AppInfo(pm, pi.applicationInfo);
295 | app.setImageDrawable(appInfo.getIcon())
296 | .setText(appInfo.getName())
297 | .setPackageName(appInfo.getPackageName());
298 | }
299 | } else {
300 | app.setImageResource(R.drawable.ic_add)
301 | .setText("")
302 | .setPackageName(null);
303 | }
304 | } catch (Exception e) {
305 | e.printStackTrace();
306 | }
307 | }
308 |
309 | @Override
310 | public void onStart() {
311 | super.onStart();
312 | setClock();
313 | if (mSetup.showBattery() && !mBatteryChangedReceiverRegistered) {
314 | getActivity().registerReceiver(this.mBatteryChangedReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
315 | mBatteryChangedReceiverRegistered = true;
316 | }
317 | mHandler.postDelayed(mTimerTick, 1000);
318 | }
319 |
320 | @Override
321 | public void onPause() {
322 | super.onPause();
323 | mHandler.removeCallbacks(mTimerTick);
324 | if (mBatteryChangedReceiverRegistered) {
325 | getActivity().unregisterReceiver(this.mBatteryChangedReceiver);
326 | }
327 | }
328 |
329 | private void setClock() {
330 | Date date = new Date(System.currentTimeMillis());
331 | mClock.setText(mTimeFormat.format(date));
332 | mDate.setText(mDateFormat.format(date));
333 | mHandler.postDelayed(mTimerTick, 1000);
334 | }
335 |
336 | @Override
337 | public boolean onLongClick(View v) {
338 | if (v instanceof ApplicationView) {
339 | ApplicationView appView = (ApplicationView) v;
340 | if (appView.hasPackage() && mSetup.iconsLocked()) {
341 | Toast.makeText(getActivity(), R.string.home_locked, Toast.LENGTH_SHORT).show();
342 | } else {
343 | openApplicationList(ApplicationList.VIEW_LIST, appView.getPosition(), appView.hasPackage(), REQUEST_CODE_APPLICATION_LIST);
344 | }
345 | return (true);
346 | }
347 | return (false);
348 | }
349 |
350 | @Override
351 | public void onClick(View v) {
352 | if (v instanceof ApplicationView) {
353 | openApplication((ApplicationView) v);
354 | return;
355 | }
356 |
357 | switch (v.getId()) {
358 | case R.id.application_grid: {
359 | openApplicationList(ApplicationList.VIEW_GRID, 0, false, REQUEST_CODE_APPLICATION_START);
360 | }
361 | break;
362 |
363 | case R.id.settings:
364 | startActivityForResult(new Intent(getContext(), Preferences.class), REQUEST_CODE_PREFERENCES);
365 | break;
366 | }
367 |
368 | }
369 |
370 | private void openApplication(ApplicationView v) {
371 | if (v.hasPackage() == false) {
372 | openApplicationList(ApplicationList.VIEW_LIST, v.getPosition(), false, REQUEST_CODE_APPLICATION_LIST);
373 | return;
374 | }
375 |
376 | try {
377 | Toast.makeText(getActivity(), v.getName(), Toast.LENGTH_SHORT).show();
378 | startActivity(getLaunchIntentForPackage(v.getPackageName()));
379 | } catch (Exception e) {
380 | Toast.makeText(getActivity(), v.getName() + " : " + e.getMessage(), Toast.LENGTH_LONG).show();
381 | }
382 | }
383 |
384 | private void openApplication(String packageName) {
385 | try {
386 | Intent startApp = getLaunchIntentForPackage(packageName);
387 | Toast.makeText(getActivity(), packageName, Toast.LENGTH_SHORT).show();
388 | startActivity(startApp);
389 | } catch (Exception e) {
390 | Toast.makeText(getActivity(), packageName + " : " + e.getMessage(), Toast.LENGTH_LONG).show();
391 | }
392 | }
393 |
394 | private void openApplicationList(int viewType, int appNum, boolean showDelete, int requestCode) {
395 | Intent intent = new Intent(getActivity(), ApplicationList.class);
396 | intent.putExtra(ApplicationList.APPLICATION_NUMBER, appNum);
397 | intent.putExtra(ApplicationList.VIEW_TYPE, viewType);
398 | intent.putExtra(ApplicationList.SHOW_DELETE, showDelete);
399 | startActivityForResult(intent, requestCode);
400 | }
401 |
402 | private Intent getLaunchIntentForPackage(String packageName) {
403 | PackageManager pm = getActivity().getPackageManager();
404 | Intent launchIntent = pm.getLaunchIntentForPackage(packageName);
405 |
406 | if(launchIntent == null) {
407 | launchIntent = pm.getLeanbackLaunchIntentForPackage(packageName);
408 | }
409 |
410 | return launchIntent;
411 | }
412 |
413 | @Override
414 | public void onActivityResult(int requestCode, int resultCode, Intent intent) {
415 | super.onActivityResult(requestCode, resultCode, intent);
416 | switch (requestCode) {
417 | case REQUEST_CODE_WALLPAPER:
418 | break;
419 | case REQUEST_CODE_PREFERENCES:
420 | restartActivity();
421 | break;
422 | case REQUEST_CODE_APPLICATION_START:
423 | if (intent != null)
424 | openApplication(intent.getExtras().getString(ApplicationList.PACKAGE_NAME));
425 | break;
426 | case REQUEST_CODE_APPLICATION_LIST:
427 | if (resultCode == Activity.RESULT_OK) {
428 | Bundle extra = intent.getExtras();
429 | int appNum = intent.getExtras().getInt(ApplicationList.APPLICATION_NUMBER);
430 |
431 | if (extra.containsKey(ApplicationList.DELETE) && extra.getBoolean(ApplicationList.DELETE)) {
432 | writePreferences(appNum, null);
433 | } else {
434 | writePreferences(appNum,
435 | intent.getExtras().getString(ApplicationList.PACKAGE_NAME)
436 | );
437 | }
438 | updateApplications();
439 | }
440 | break;
441 | }
442 | }
443 |
444 |
445 | }
446 |
--------------------------------------------------------------------------------