4 * Authors: Nathaniel McCallum <npmccallum@redhat.com>
6 * Copyright (C) 2013 Nathaniel McCallum, Red Hat
7 * see file 'COPYING' for use and warranty information
9 * This program is free software you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * Portions Copyright 2009 ZXing authors
26 * Licensed under the Apache License, Version 2.0 (the "License");
27 * you may not use this file except in compliance with the License.
28 * You may obtain a copy of the License at
30 * http://www.apache.org/licenses/LICENSE-2.0
32 * Unless required by applicable law or agreed to in writing, software
33 * distributed under the License is distributed on an "AS IS" BASIS,
34 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 * See the License for the specific language governing permissions and
36 * limitations under the License.
39 package org.fedorahosted.freeotp;
41 import java.security.NoSuchAlgorithmException;
42 import java.util.Arrays;
43 import java.util.List;
45 import org.fedorahosted.freeotp.Token.TokenUriInvalidException;
47 import android.net.Uri;
48 import android.os.Bundle;
49 import android.app.AlertDialog;
50 import android.app.ListActivity;
51 import android.content.ActivityNotFoundException;
52 import android.content.DialogInterface;
53 import android.content.Intent;
54 import android.content.pm.PackageManager;
55 import android.content.pm.ResolveInfo;
56 import android.view.Menu;
57 import android.view.MenuItem;
58 import android.view.MenuItem.OnMenuItemClickListener;
59 import android.widget.Toast;
61 public class MainActivity extends ListActivity {
62 private static final String ACTION_SCAN = "com.google.zxing.client.android.SCAN";
63 private static final List<String> PROVIDERS = Arrays.asList(new String[] {
64 "com.google.zxing.client.android", // Barcode Scanner
65 "com.srowen.bs.android", // Barcode Scanner+
66 "com.srowen.bs.android.simple", // Barcode Scanner+ Simple
67 "com.google.android.apps.unveil" // Google Goggles
70 private TokenAdapter ta;
72 private String findAppPackage(Intent i) {
73 PackageManager pm = getPackageManager();
74 List<ResolveInfo> ril = pm.queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY);
76 for (ResolveInfo ri : ril) {
77 if (PROVIDERS.contains(ri.activityInfo.packageName))
78 return ri.activityInfo.packageName;
86 protected void onCreate(Bundle savedInstanceState) {
87 super.onCreate(savedInstanceState);
88 setContentView(R.layout.main);
89 ta = new TokenAdapter(this);
94 public boolean onCreateOptionsMenu(Menu menu) {
95 getMenuInflater().inflate(R.menu.main, menu);
97 menu.findItem(R.id.action_add).setOnMenuItemClickListener(new OnMenuItemClickListener() {
98 public boolean onMenuItemClick(MenuItem item) {
99 Intent i = new Intent(ACTION_SCAN);
100 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
101 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
102 i.addCategory(Intent.CATEGORY_DEFAULT);
103 i.putExtra("SCAN_MODE", "QR_CODE_MODE");
104 i.putExtra("SAVE_HISTORY", false);
106 String pkg = findAppPackage(i);
109 startActivityForResult(i, 0);
113 new AlertDialog.Builder(MainActivity.this)
114 .setTitle(R.string.install_title)
115 .setMessage(R.string.install_message)
116 .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
117 public void onClick(DialogInterface dialogInterface, int i) {
118 Uri uri = Uri.parse("market://details?id=" + PROVIDERS.get(0));
119 Intent intent = new Intent(Intent.ACTION_VIEW, uri);
121 startActivity(intent);
122 } catch (ActivityNotFoundException e) {
127 .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
128 public void onClick(DialogInterface dialogInterface, int i) {
141 public void onActivityResult(int requestCode, int resultCode, Intent intent) {
142 if (resultCode == RESULT_OK) {
144 ta.add(this, intent.getStringExtra("SCAN_RESULT"));
145 } catch (NoSuchAlgorithmException e) {
146 Toast.makeText(this, R.string.token_scan_invalid, Toast.LENGTH_SHORT).show();
148 } catch (TokenUriInvalidException e) {
149 Toast.makeText(this, R.string.token_scan_invalid, Toast.LENGTH_SHORT).show();