Updates for Android 4+

git-svn-id: https://zxing.googlecode.com/svn/trunk@2880 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen@gmail.com 2013-09-01 08:59:08 +00:00
parent 551c80941f
commit 0d6eabd6fc
39 changed files with 248 additions and 414 deletions

View file

@ -16,8 +16,8 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.zxing.client.android"
android:versionName="4.4.1"
android:versionCode="92"
android:versionName="4.5"
android:versionCode="93"
android:installLocation="auto">
<uses-permission android:name="android.permission.CAMERA"/>
@ -30,7 +30,7 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="18"/>
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="18"/>
<!-- Don't require camera, as this requires a rear camera. This allows it to work on the Nexus 7 -->
<uses-feature android:name="android.hardware.camera" android:required="false"/>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p> Neu in Version 4.4.1: </p>
<p> Neu in Version 4.5: </p>
<ul>
<li> Nun erfordert Android 4.0.3 oder höher. </li>
<li> Google Shopper Link wurde entfernt. </li>
<li> Kleine Korrekturen und Verbesserungen. </li>
</ul>

View file

@ -6,8 +6,9 @@
<link rel="stylesheet" href="../style.css" type="text/css"/>
</head>
<body>
<p>New in version 4.4.1:</p>
<p>New in version 4.5:</p>
<ul>
<li>Now requires Android 4.0.3 or later.</li>
<li>Google Shopper link has been removed.</li>
<li>Small fixes and improvements.</li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p> Nuevo en la versión 4.4.1: </p>
<p> Nuevo en la versión 4.5: </p>
<ul>
<li> Ahora requiere Android 4.0.3 o posterior. </li>
<li> Enlace Shopper Google ha eliminado. </li>
<li> Correcciones y mejoras pequeñas. </li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p> Nouveau dans la version 4.4.1: </p>
<p> Nouveau dans la version 4.5: </p>
<ul>
<li> Maintenant VERSION ANDROID 4.0.3 ou ultérieur. </li>
<li> Lien Google Shopper a été éliminée. </li>
<li> Quelques petites corrections et améliorations. </li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p> Novità nella versione 4.4.1: </p>
<p> Nuovo nella versione 4.5: </p>
<ul>
<li> Ora Versione Android 4.0.3 o versione successiva. </li>
<li> Collegamento Shopper Google è stato rimosso. </li>
<li> Piccole correzioni e miglioramenti. </li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p> バージョン4.4.1の新機能: </p>
<p> バージョン4.5の新機能: </p>
<ul>
<li> 今アンドロイド4.0.3以降が必要です。 </li>
<li> Googleのショッパーリンクが削除されました。 </li>
<li> 小さな修正と改善。 </li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p> 버전 4.4.1의 새로운 기능 : </p>
<p> 버전 4.5의 새로운 기능 : </p>
<ul>
<li> 지금 인조 인간 4.0.3 또는 이후 버전이 필요합니다. </li>
<li> 구글 쇼퍼 링크가 제거되었습니다. </li>
<li> 작은 수정 사항 및 개선. </li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p> Nieuw in versie 4.4.1: </p>
<p> Nieuw in versie 4.5: </p>
<ul>
<li> Nu Android 4.0.3 of hoger vereist. </li>
<li> Google Shopper koppeling is verwijderd. </li>
<li> Kleine fixes en verbeteringen. </li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p> Novo na versão 4.4.1: </p>
<p> Novo na versão 4.5: </p>
<ul>
<li> Agora requer Android 4.0.3 ou posterior. </li>
<li> Ligação Shopper Google foi removida. </li>
<li> Pequenas correções e melhorias. </li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p> Новое в версии 4.4.1: </p>
<p> Новое в версии 4.5: </p>
<ul>
<li> Теперь требуется Android 4.0.3 или более поздней. </li>
<li> Google Shopper ссылка была удалена. </li>
<li> Мелкие исправления и улучшения. </li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p>版本4.4.1 </p>
<p>的4.5版中 </p>
<ul>
<li> 现在需要Android 4.0.3或更高版本。 </li>
<li> 谷歌购物的链接已被删除。 </li>
<li> 小的修正和改进。 </li>
</ul>

View file

@ -6,8 +6,9 @@
<link href="../style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<p>版本4.4.1 </p>
<p>的4.5版中 </p>
<ul>
<li> 現在需要Android 4.0.3或更高版本。 </li>
<li> 谷歌購物的鏈接已被刪除。 </li>
<li> 小的修正和改進。 </li>
</ul>

View file

@ -38,6 +38,7 @@
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scaleType="center"
android:src="@drawable/share_via_barcode"
android:paddingRight="24dip"/>
@ -49,13 +50,11 @@
android:orientation="vertical">
<Button android:id="@+id/share_app_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/ShareButton"
android:text="@string/button_share_app"/>
<Button android:id="@+id/share_contact_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/ShareButton"
android:text="@string/button_share_contact"/>
</LinearLayout>
@ -67,13 +66,11 @@
android:orientation="vertical">
<Button android:id="@+id/share_bookmark_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/ShareButton"
android:text="@string/button_share_bookmark"/>
<Button android:id="@+id/share_clipboard_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/ShareButton"
android:text="@string/button_share_clipboard"/>
</LinearLayout>

View file

@ -14,9 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<SurfaceView android:id="@+id/preview_view"
android:layout_width="fill_parent"
@ -176,24 +174,16 @@
android:layout_height="wrap_content"
android:gravity="center">
<Button android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
<Button style="@style/ResultButton"
android:visibility="gone"/>
<Button android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
<Button style="@style/ResultButton"
android:visibility="gone"/>
<Button android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
<Button style="@style/ResultButton"
android:visibility="gone"/>
<Button android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
<Button style="@style/ResultButton"
android:visibility="gone"/>
</LinearLayout>
@ -208,4 +198,4 @@
android:text="@string/msg_default_status"
android:textColor="@color/status_text"/>
</FrameLayout>
</merge>

View file

@ -14,9 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<SurfaceView android:id="@+id/preview_view"
android:layout_width="fill_parent"
@ -175,24 +173,16 @@
android:orientation="horizontal"
android:gravity="center">
<Button android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
<Button style="@style/ResultButton"
android:visibility="gone"/>
<Button android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
<Button style="@style/ResultButton"
android:visibility="gone"/>
<Button android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
<Button style="@style/ResultButton"
android:visibility="gone"/>
<Button android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
<Button style="@style/ResultButton"
android:visibility="gone"/>
</LinearLayout>
@ -207,4 +197,4 @@
android:text="@string/msg_default_status"
android:textColor="@color/status_text"/>
</FrameLayout>
</merge>

View file

@ -35,6 +35,7 @@
android:inputType="text"/>
<Button android:id="@+id/query_button"
style="@android:style/Widget.Holo.Button.Borderless.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"

View file

@ -51,14 +51,12 @@
android:paddingBottom="@dimen/standard_padding">
<Button android:id="@+id/share_app_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/ShareButton"
android:layout_weight="1"
android:text="@string/button_share_app"/>
<Button android:id="@+id/share_bookmark_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/ShareButton"
android:layout_weight="1"
android:text="@string/button_share_bookmark"/>
@ -71,14 +69,12 @@
android:paddingBottom="@dimen/standard_padding">
<Button android:id="@+id/share_contact_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/ShareButton"
android:layout_weight="1"
android:text="@string/button_share_contact"/>
<Button android:id="@+id/share_clipboard_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="@style/ShareButton"
android:layout_weight="1"
android:text="@string/button_share_clipboard"/>

View file

@ -15,10 +15,15 @@
limitations under the License.
-->
<resources>
<style name="CaptureTheme" parent="android:Theme.Holo">
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActionModeOverlay">true</item>
<style name="ResultButton" parent="@android:style/Widget.Holo.Button.Borderless.Small">
<item name="android:layout_width">0dip</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
</style>
<style name="ShareButton" parent="@android:style/Widget.Holo.Button.Borderless.Small">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
</resources>

View file

@ -15,5 +15,10 @@
limitations under the License.
-->
<resources>
<style name="CaptureTheme" parent="android:Theme.NoTitleBar.Fullscreen"/>
<style name="CaptureTheme" parent="android:Theme.Holo">
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActionModeOverlay">true</item>
</style>
</resources>

View file

@ -22,6 +22,7 @@ import com.google.zxing.Result;
import com.google.zxing.ResultMetadataType;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.camera.CameraManager;
import com.google.zxing.client.android.clipboard.ClipboardInterface;
import com.google.zxing.client.android.history.HistoryActivity;
import com.google.zxing.client.android.history.HistoryItem;
import com.google.zxing.client.android.history.HistoryManager;
@ -44,7 +45,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.text.ClipboardManager;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
@ -173,7 +173,6 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
} else {
// Install the callback and wait for surfaceCreated() to init the camera.
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
beepManager.updatePrefs();
@ -560,15 +559,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
}
if (copyToClipboard && !resultHandler.areContentsSecure()) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
if (displayContents != null) {
try {
clipboard.setText(displayContents);
} catch (NullPointerException npe) {
// Some kind of bug inside the clipboard implementation, not due to null input
Log.w(TAG, "Clipboard bug", npe);
}
}
ClipboardInterface.setText(displayContents, this);
}
}
@ -596,16 +587,8 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
}
if (copyToClipboard && !resultHandler.areContentsSecure()) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
CharSequence text = resultHandler.getDisplayContents();
if (text != null) {
try {
clipboard.setText(text);
} catch (NullPointerException npe) {
// Some kind of bug inside the clipboard implementation, not due to null input
Log.w(TAG, "Clipboard bug", npe);
}
}
ClipboardInterface.setText(text, this);
}
if (source == IntentSource.NATIVE_APP_INTENT) {

View file

@ -25,9 +25,6 @@ import android.os.AsyncTask;
import android.os.BatteryManager;
import android.util.Log;
import com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;
import com.google.zxing.client.android.common.executor.AsyncTaskExecManager;
/**
* Finishes an activity after a period of inactivity if the device is on battery power.
*/
@ -38,13 +35,11 @@ final class InactivityTimer {
private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;
private final Activity activity;
private final AsyncTaskExecInterface taskExec;
private final BroadcastReceiver powerStatusReceiver;
private AsyncTask<?,?,?> inactivityTask;
InactivityTimer(Activity activity) {
this.activity = activity;
taskExec = new AsyncTaskExecManager().build();
powerStatusReceiver = new PowerStatusReceiver();
onActivity();
}
@ -52,7 +47,7 @@ final class InactivityTimer {
synchronized void onActivity() {
cancel();
inactivityTask = new InactivityAsyncTask();
taskExec.execute(inactivityTask);
inactivityTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void onPause() {

View file

@ -16,23 +16,16 @@
package com.google.zxing.client.android;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.app.Activity;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import java.util.ArrayList;
import java.util.Collection;
/**
* The main settings activity.
*
* @author dswitkin@google.com (Daniel Switkin)
* @author Sean Owen
*/
public final class PreferencesActivity extends PreferenceActivity
implements OnSharedPreferenceChangeListener {
public final class PreferencesActivity extends Activity {
public static final String KEY_DECODE_1D = "preferences_decode_1D";
public static final String KEY_DECODE_QR = "preferences_decode_QR";
@ -53,44 +46,11 @@ public final class PreferencesActivity extends PreferenceActivity
public static final String KEY_DISABLE_CONTINUOUS_FOCUS = "preferences_disable_continuous_focus";
//public static final String KEY_DISABLE_EXPOSURE = "preferences_disable_exposure";
private CheckBoxPreference decode1D;
private CheckBoxPreference decodeQR;
private CheckBoxPreference decodeDataMatrix;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.preferences);
getFragmentManager().beginTransaction().replace(android.R.id.content, new PreferencesFragment()).commit();
PreferenceGroup preferences = getPreferenceScreen();
preferences.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
decode1D = (CheckBoxPreference) preferences.findPreference(KEY_DECODE_1D);
decodeQR = (CheckBoxPreference) preferences.findPreference(KEY_DECODE_QR);
decodeDataMatrix = (CheckBoxPreference) preferences.findPreference(KEY_DECODE_DATA_MATRIX);
disableLastCheckedPref();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
disableLastCheckedPref();
}
private void disableLastCheckedPref() {
Collection<CheckBoxPreference> checked = new ArrayList<CheckBoxPreference>(3);
if (decode1D.isChecked()) {
checked.add(decode1D);
}
if (decodeQR.isChecked()) {
checked.add(decodeQR);
}
if (decodeDataMatrix.isChecked()) {
checked.add(decodeDataMatrix);
}
boolean disable = checked.size() < 2;
CheckBoxPreference[] checkBoxPreferences = {decode1D, decodeQR, decodeDataMatrix};
for (CheckBoxPreference pref : checkBoxPreferences) {
pref.setEnabled(!(disable && checked.contains(pref)));
}
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (C) 2013 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.client.android;
import java.util.ArrayList;
import java.util.Collection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
public final class PreferencesFragment
extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener {
private CheckBoxPreference decode1D;
private CheckBoxPreference decodeQR;
private CheckBoxPreference decodeDataMatrix;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.preferences);
PreferenceScreen preferences = getPreferenceScreen();
preferences.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
decode1D = (CheckBoxPreference) preferences.findPreference(PreferencesActivity.KEY_DECODE_1D);
decodeQR = (CheckBoxPreference) preferences.findPreference(PreferencesActivity.KEY_DECODE_QR);
decodeDataMatrix = (CheckBoxPreference) preferences.findPreference(PreferencesActivity.KEY_DECODE_DATA_MATRIX);
disableLastCheckedPref();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
disableLastCheckedPref();
}
private void disableLastCheckedPref() {
Collection<CheckBoxPreference> checked = new ArrayList<CheckBoxPreference>(3);
if (decode1D.isChecked()) {
checked.add(decode1D);
}
if (decodeQR.isChecked()) {
checked.add(decodeQR);
}
if (decodeDataMatrix.isChecked()) {
checked.add(decodeDataMatrix);
}
boolean disable = checked.size() < 2;
CheckBoxPreference[] checkBoxPreferences = {decode1D, decodeQR, decodeDataMatrix};
for (CheckBoxPreference pref : checkBoxPreferences) {
pref.setEnabled(!(disable && checked.contains(pref)));
}
}
}

View file

@ -44,8 +44,6 @@ import com.google.zxing.client.android.Intents;
import com.google.zxing.client.android.HttpHelper;
import com.google.zxing.client.android.LocaleManager;
import com.google.zxing.client.android.R;
import com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;
import com.google.zxing.client.android.common.executor.AsyncTaskExecManager;
/**
* Uses Google Book Search to find a word or phrase in the requested book.
@ -68,11 +66,6 @@ public final class SearchBookContentsActivity extends Activity {
private ListView resultListView;
private TextView headerView;
private AsyncTask<String,?,?> networkTask;
private final AsyncTaskExecInterface taskExec;
public SearchBookContentsActivity() {
taskExec = new AsyncTaskExecManager().build();
}
private final Button.OnClickListener buttonListener = new Button.OnClickListener() {
@Override
@ -161,7 +154,7 @@ public final class SearchBookContentsActivity extends Activity {
oldTask.cancel(true);
}
networkTask = new NetworkTask();
taskExec.execute(networkTask, query, isbn);
networkTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, query, isbn);
headerView.setText(R.string.msg_sbc_searching_book);
resultListView.setAdapter(null);
queryTextView.setEnabled(false);

View file

@ -27,8 +27,6 @@ import java.util.ArrayList;
import java.util.Collection;
import com.google.zxing.client.android.PreferencesActivity;
import com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;
import com.google.zxing.client.android.common.executor.AsyncTaskExecManager;
final class AutoFocusManager implements Camera.AutoFocusCallback {
@ -46,11 +44,9 @@ final class AutoFocusManager implements Camera.AutoFocusCallback {
private final boolean useAutoFocus;
private final Camera camera;
private AsyncTask<?,?,?> outstandingTask;
private final AsyncTaskExecInterface taskExec;
AutoFocusManager(Context context, Camera camera) {
this.camera = camera;
taskExec = new AsyncTaskExecManager().build();
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
String currentFocusMode = camera.getParameters().getFocusMode();
useAutoFocus =
@ -64,7 +60,7 @@ final class AutoFocusManager implements Camera.AutoFocusCallback {
public synchronized void onAutoFocus(boolean success, Camera theCamera) {
if (active) {
outstandingTask = new AutoFocusTask();
taskExec.execute(outstandingTask);
outstandingTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}

View file

@ -65,17 +65,9 @@ final class CameraConfigurationManager {
Camera.Parameters parameters = camera.getParameters();
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
// We're landscape-only, and have apparently seen issues with display thinking it's portrait
// when waking from sleep. If it's not landscape, assume it's mistaken and reverse them:
if (width < height) {
Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
int temp = width;
width = height;
height = temp;
}
screenResolution = new Point(width, height);
Point theScreenResolution = new Point();
display.getSize(theScreenResolution);
screenResolution = theScreenResolution;
Log.i(TAG, "Screen resolution: " + screenResolution);
cameraResolution = findBestPreviewSizeValue(parameters, screenResolution);
Log.i(TAG, "Camera resolution: " + cameraResolution);
@ -106,8 +98,8 @@ final class CameraConfigurationManager {
Camera.Parameters.FOCUS_MODE_AUTO);
} else {
focusMode = findSettableValue(parameters.getSupportedFocusModes(),
"continuous-picture", // Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE in 4.0+
"continuous-video", // Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO in 4.0+
Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE,
Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO,
Camera.Parameters.FOCUS_MODE_AUTO);
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (C) 2012 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.client.android.clipboard;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.util.Log;
public final class ClipboardInterface {
private static final String TAG = ClipboardInterface.class.getSimpleName();
private ClipboardInterface() {
}
public static CharSequence getText(Context context) {
ClipboardManager clipboard = getManager(context);
ClipData clip = clipboard.getPrimaryClip();
return hasText(context) ? clip.getItemAt(0).coerceToText(context) : null;
}
public static void setText(CharSequence text, Context context) {
if (text != null) {
try {
getManager(context).setPrimaryClip(ClipData.newPlainText(null, text));
} catch (NullPointerException npe) {
// Have seen this in the wild, bizarrely
Log.w(TAG, "Clipboard bug", npe);
}
}
}
public static boolean hasText(Context context) {
ClipboardManager clipboard = getManager(context);
ClipData clip = clipboard.getPrimaryClip();
return clip != null && clip.getItemCount() > 0;
}
private static ClipboardManager getManager(Context context) {
return (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
}
}

View file

@ -1,94 +0,0 @@
/*
* Copyright (C) 2012 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.client.android.common;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* <p>Sometimes the application wants to access advanced functionality exposed by Android APIs that are only available
* in later versions of the platform. While {@code Build.VERSION} can be used to determine the device's API level
* and alter behavior accordingly, and it is possible to write code that uses both old and new APIs selectively,
* such code would fail to load on older devices that do not have the new API methods.</p>
*
* <p>It is necessary to only load classes that use newer APIs than the device may support after the app
* has checked the API level. This requires reflection, loading one of several implementations based on the
* API level.</p>
*
* <p>This class manages that process. Subclasses of this class manage access to implementations of a given interface
* in an API-level-aware way. Subclasses implementation classes <em>by name</em>, and the minimum API level that
* the implementation is compatible with. They also provide a default implementation.</p>
*
* <p>At runtime an appropriate implementation is then chosen, instantiated and returned from {@link #build()}.</p>
*
* @param <T> the interface which managed implementations implement
*/
public abstract class PlatformSupportManager<T> {
private static final String TAG = PlatformSupportManager.class.getSimpleName();
private final Class<T> managedInterface;
private final T defaultImplementation;
private final SortedMap<Integer,String> implementations;
protected PlatformSupportManager(Class<T> managedInterface, T defaultImplementation) {
if (!managedInterface.isInterface()) {
throw new IllegalArgumentException();
}
if (!managedInterface.isInstance(defaultImplementation)) {
throw new IllegalArgumentException();
}
this.managedInterface = managedInterface;
this.defaultImplementation = defaultImplementation;
this.implementations = new TreeMap<Integer,String>(Collections.reverseOrder());
}
protected final void addImplementationClass(int minVersion, String className) {
implementations.put(minVersion, className);
}
public final T build() {
for (Integer minVersion : implementations.keySet()) {
if (Build.VERSION.SDK_INT >= minVersion) {
String className = implementations.get(minVersion);
try {
Class<? extends T> clazz = Class.forName(className).asSubclass(managedInterface);
Log.i(TAG, "Using implementation " + clazz + " of " + managedInterface + " for SDK " + minVersion);
return clazz.getConstructor().newInstance();
} catch (ClassNotFoundException cnfe) {
Log.w(TAG, cnfe);
} catch (IllegalAccessException iae) {
Log.w(TAG, iae);
} catch (InstantiationException ie) {
Log.w(TAG, ie);
} catch (NoSuchMethodException nsme) {
Log.w(TAG, nsme);
} catch (InvocationTargetException ite) {
Log.w(TAG, ite);
}
}
}
Log.i(TAG, "Using default implementation " + defaultImplementation.getClass() + " of " + managedInterface);
return defaultImplementation;
}
}

View file

@ -1,25 +0,0 @@
/*
* Copyright (C) 2012 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.client.android.common.executor;
import android.os.AsyncTask;
public interface AsyncTaskExecInterface {
<T> void execute(AsyncTask<T,?,?> task, T... args);
}

View file

@ -1,28 +0,0 @@
/*
* Copyright (C) 2012 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.client.android.common.executor;
import com.google.zxing.client.android.common.PlatformSupportManager;
public final class AsyncTaskExecManager extends PlatformSupportManager<AsyncTaskExecInterface> {
public AsyncTaskExecManager() {
super(AsyncTaskExecInterface.class, new DefaultAsyncTaskExecInterface());
addImplementationClass(11, "com.google.zxing.client.android.common.executor.HoneycombAsyncTaskExecInterface");
}
}

View file

@ -1,32 +0,0 @@
/*
* Copyright (C) 2012 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.client.android.common.executor;
import android.os.AsyncTask;
/**
* Before Honeycomb, {@link AsyncTask} uses parallel execution by default, which is desired. Good thing
* too since there is no API to request otherwise.
*/
public final class DefaultAsyncTaskExecInterface implements AsyncTaskExecInterface {
@Override
public <T> void execute(AsyncTask<T,?,?> task, T... args) {
task.execute(args);
}
}

View file

@ -1,34 +0,0 @@
/*
* Copyright (C) 2012 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.client.android.common.executor;
import android.annotation.TargetApi;
import android.os.AsyncTask;
/**
* On Honeycomb and later, {@link AsyncTask} returns to serial execution by default which is undesirable.
* This calls Honeycomb-only APIs to request parallel execution.
*/
@TargetApi(11)
public final class HoneycombAsyncTaskExecInterface implements AsyncTaskExecInterface {
@Override
public <T> void execute(AsyncTask<T,?,?> task, T... args) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, args);
}
}

View file

@ -16,6 +16,7 @@
package com.google.zxing.client.android.encode;
import android.graphics.Point;
import android.view.Display;
import android.view.MenuInflater;
import android.view.WindowManager;
@ -186,8 +187,10 @@ public final class EncodeActivity extends Activity {
// This assumes the view is full screen, which is a good assumption
WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Point displaySize = new Point();
display.getSize(displaySize);
int width = displaySize.x;
int height = displaySize.y;
int smallerDimension = width < height ? width : height;
smallerDimension = smallerDimension * 7 / 8;

View file

@ -19,13 +19,12 @@ package com.google.zxing.client.android.result;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import com.google.zxing.client.android.CaptureActivity;
import com.google.zxing.client.android.R;
import com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;
import com.google.zxing.client.android.common.executor.AsyncTaskExecManager;
import com.google.zxing.client.android.wifi.WifiConfigManager;
import com.google.zxing.client.result.ParsedResult;
import com.google.zxing.client.result.WifiParsedResult;
@ -41,12 +40,10 @@ public final class WifiResultHandler extends ResultHandler {
private static final String TAG = WifiResultHandler.class.getSimpleName();
private final CaptureActivity parent;
private final AsyncTaskExecInterface taskExec;
public WifiResultHandler(CaptureActivity activity, ParsedResult result) {
super(activity, result);
parent = activity;
taskExec = new AsyncTaskExecManager().build();
}
@Override
@ -76,7 +73,7 @@ public final class WifiResultHandler extends ResultHandler {
Toast.makeText(activity.getApplicationContext(), R.string.wifi_changing_network, Toast.LENGTH_SHORT).show();
}
});
taskExec.execute(new WifiConfigManager(wifiManager), wifiResult);
new WifiConfigManager(wifiManager).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, wifiResult);
parent.restartPreviewAfterDelay(0L);
}
}

View file

@ -31,8 +31,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;
import com.google.zxing.client.android.common.executor.AsyncTaskExecManager;
import com.google.zxing.client.android.history.HistoryManager;
import com.google.zxing.client.result.ISBNParsedResult;
import com.google.zxing.client.result.ParsedResult;
@ -47,28 +45,43 @@ public abstract class SupplementalInfoRetriever extends AsyncTask<Object,Object,
ParsedResult result,
HistoryManager historyManager,
Context context) {
AsyncTaskExecInterface taskExec = new AsyncTaskExecManager().build();
if (result instanceof URIParsedResult) {
taskExec.execute(new URIResultInfoRetriever(textView, (URIParsedResult) result, historyManager, context));
taskExec.execute(new TitleRetriever(textView, (URIParsedResult) result, historyManager));
SupplementalInfoRetriever uriRetriever =
new URIResultInfoRetriever(textView, (URIParsedResult) result, historyManager, context);
uriRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
SupplementalInfoRetriever titleRetriever =
new TitleRetriever(textView, (URIParsedResult) result, historyManager);
titleRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else if (result instanceof ProductParsedResult) {
ProductParsedResult productParsedResult = (ProductParsedResult) result;
String productID = productParsedResult.getProductID();
String normalizedProductID = productParsedResult.getNormalizedProductID();
taskExec.execute(new ProductResultInfoRetriever(textView, productID, historyManager, context));
SupplementalInfoRetriever productRetriever =
new ProductResultInfoRetriever(textView, productID, historyManager, context);
productRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
switch (productID.length()) {
case 12:
taskExec.execute(new AmazonInfoRetriever(textView, "UPC", normalizedProductID, historyManager, context));
SupplementalInfoRetriever upcInfoRetriever =
new AmazonInfoRetriever(textView, "UPC", normalizedProductID, historyManager, context);
upcInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
break;
case 13:
taskExec.execute(new AmazonInfoRetriever(textView, "EAN", normalizedProductID, historyManager, context));
SupplementalInfoRetriever eanInfoRetriever =
new AmazonInfoRetriever(textView, "EAN", normalizedProductID, historyManager, context);
eanInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
break;
}
} else if (result instanceof ISBNParsedResult) {
String isbn = ((ISBNParsedResult) result).getISBN();
taskExec.execute(new ProductResultInfoRetriever(textView, isbn, historyManager, context));
taskExec.execute(new BookResultInfoRetriever(textView, isbn, historyManager, context));
taskExec.execute(new AmazonInfoRetriever(textView, "ISBN", isbn, historyManager, context));
SupplementalInfoRetriever productInfoRetriever =
new ProductResultInfoRetriever(textView, isbn, historyManager, context);
productInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
SupplementalInfoRetriever bookInfoRetriever =
new BookResultInfoRetriever(textView, isbn, historyManager, context);
bookInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
SupplementalInfoRetriever amazonInfoRetriever =
new AmazonInfoRetriever(textView, "ISBN", isbn, historyManager, context);
amazonInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}

View file

@ -24,23 +24,15 @@ import android.view.View;
import android.widget.Adapter;
import android.widget.ListView;
import com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;
import com.google.zxing.client.android.common.executor.AsyncTaskExecManager;
public final class AppPickerActivity extends ListActivity {
private AsyncTask<?,?,?> backgroundTask;
private final AsyncTaskExecInterface taskExec;
public AppPickerActivity() {
taskExec = new AsyncTaskExecManager().build();
}
@Override
protected void onResume() {
super.onResume();
backgroundTask = new LoadPackagesAsyncTask(this);
taskExec.execute(backgroundTask);
backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override

View file

@ -30,12 +30,12 @@ import android.net.Uri;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.provider.Browser;
import android.text.ClipboardManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.zxing.client.android.clipboard.ClipboardInterface;
/**
* Barcode Scanner can share data like contacts and bookmarks by displaying a QR Code on screen,
@ -85,10 +85,10 @@ public final class ShareActivity extends Activity {
private final Button.OnClickListener clipboardListener = new Button.OnClickListener() {
@Override
public void onClick(View v) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
// Should always be true, because we grey out the clipboard button in onResume() if it's empty
if (clipboard.hasText()) {
launchSearch(clipboard.getText().toString());
CharSequence text = ClipboardInterface.getText(ShareActivity.this);
if (text != null) {
launchSearch(text.toString());
}
}
};
@ -132,8 +132,7 @@ public final class ShareActivity extends Activity {
@Override
protected void onResume() {
super.onResume();
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
clipboardButton.setEnabled(clipboard.hasText());
clipboardButton.setEnabled(ClipboardInterface.hasText(this));
}
@Override

View file

@ -16,14 +16,13 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.zxing.client.androidtest"
android:versionName="1.3"
android:versionName="1.4"
android:versionCode="8"
android:installLocation="auto">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-sdk android:minSdkVersion="10"
android:targetSdkVersion="18"/>
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="18"/>
<supports-screens android:xlargeScreens="true"
android:largeScreens="true"