I have a question. At this time, the capturePicture of WebView is deprecated.
I want to ask if there is a way to replace the function. I meant it can capture entire of the webview (not only the view is displayed)
Thanks
I finally found out the solution.
Some of codes
public class WebViewActivity extends Activity {
private static WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
webView = (WebView) findViewById(R.id.webView1);
webView.loadUrl("http://developer.android.com/reference/packages.html");
// webView.loadUrl("http://developer.android.com/training/basics/firstapp/creating-project.html");
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
webView.measure(MeasureSpec.makeMeasureSpec(
MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
webView.layout(0, 0, webView.getMeasuredWidth(),
webView.getMeasuredHeight());
webView.setDrawingCacheEnabled(true);
webView.buildDrawingCache();
Bitmap bm = Bitmap.createBitmap(webView.getMeasuredWidth(),
webView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas bigcanvas = new Canvas(bm);
Paint paint = new Paint();
int iHeight = bm.getHeight();
bigcanvas.drawBitmap(bm, 0, iHeight, paint);
webView.draw(bigcanvas);
System.out.println("1111111111111111111111="
+ bigcanvas.getWidth());
System.out.println("22222222222222222222222="
+ bigcanvas.getHeight());
if (bm != null) {
try {
String path = Environment.getExternalStorageDirectory()
.toString();
OutputStream fOut = null;
File file = new File(path, "/aaaa.png");
fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 50, fOut);
fOut.flush();
fOut.close();
bm.recycle();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
}
The layout.xml
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/webView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Use draw() method of WebView
Example :
ImageView imageview;
WebView webview;
class Background extends AsyncTask<Void, Void, Bitmap>
{
#Override
protected Bitmap doInBackground(Void... params)
{
try
{
Thread.sleep(2000);
Bitmap bitmap = Bitmap.createBitmap(webview.getWidth(), webview.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
webview.draw(canvas);
return bitmap;
}
catch (InterruptedException e){}
catch (Exception e){}
return null;
}
#Override
protected void onPostExecute(Bitmap result)
{
imageview.setImageBitmap(result);
}
}
webview.setWebChromeClient(new WebChromeClient()
{
public void onProgressChanged(WebView view, int progress)
{
if(progress==100)
new Background().execute();
}
});
Just extends BaseWebView below:
public abstract class BaseWebView extends WebView {
private static final String TAG = "BaseWebView";
private static final int DELAY_MS_MAX = 1000;
private static final int DELAY_MS_DRAW = 100;
private static final long REQUEST_ID_INIT = 0;
public BaseWebView(Context context) {
super(context);
init();
}
public BaseWebView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BaseWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* to make sure to set {#link #loadDataFinished} to true at last
* in {#link #DELAY_MS_MAX} ms later.
*/
private static final int MSG_LOAD_DATA_FINISH_DEF = 0;
/**
* to set {#link #loadDataFinished} to true in {#link #DELAY_MS_DRAW} ms later.
*/
private static final int MSG_LOAD_DATA_FINISH_DRAW = 1;
private String description;
/**
* if load data finished
* <P><P>
* mark the status for load API {#link #loadData(String, String, String)}
* & {#link #loadDataWithBaseURL(String, String, String, String, String)}
* <p>
* <b>ignored:</b> {#link #loadUrl(String)}, {#link #loadUrl(String, Map)} and {#link #reload()}
*/
private AtomicBoolean loadDataFinished = new AtomicBoolean(true);
/**
* if progress reached 1000
* <P><P>
* mark the status for load API {#link #loadData(String, String, String)}
* & {#link #loadDataWithBaseURL(String, String, String, String, String)}
* <p>
* <b>ignored:</b> {#link #loadUrl(String)}, {#link #loadUrl(String, Map)} and {#link #reload()}
*/
private AtomicBoolean progressFinished = new AtomicBoolean(true);
/**
* the request id of load data
* <P><P>
* mark the status for load API {#link #loadData(String, String, String)}
* & {#link #loadDataWithBaseURL(String, String, String, String, String)}
* <p>
* <b>ignored:</b> {#link #loadUrl(String)}, {#link #loadUrl(String, Map)} and {#link #reload()}
*/
private AtomicLong loadDataTimestamp = new AtomicLong(REQUEST_ID_INIT);
private Handler handler = new MyHandler(this);
/**
* clear status for load API {#link #loadData(String, String, String)}
* & {#link #loadDataWithBaseURL(String, String, String, String, String)}, set to false.
* <p>
* <b>ignored:</b> {#link #loadUrl(String)}, {#link #loadUrl(String, Map)} and {#link #reload()}
* <p>
* <b>Usage:</b> call in load API {#link #loadData(String, String, String)}
* & {#link #loadDataWithBaseURL(String, String, String, String, String)}
*/
private void clearLoadDataStatus() {
DLog.d(TAG, "clearLoadDataStatus: set false, obj=" + this.hashCode());
loadDataFinished.set(false);
progressFinished.set(false);
// generates a new load request id
loadDataTimestamp.set(System.currentTimeMillis());
}
private void setLoadDataFinished(long requestId) {
DLog.d(TAG, "setLoadDataFinished: id=" + requestId
+ ", loadDataTimestamp=" + loadDataTimestamp.get() + ", obj=" + this.hashCode());
if (!progressFinished.get() || requestId != loadDataTimestamp.get()) {
return;
}
loadDataFinished();
}
private void loadDataFinished() {
DLog.d(TAG, "loadDataFinished: set true, obj=" + this.hashCode());
loadDataFinished.set(true);
// clear load request id
loadDataTimestamp.set(REQUEST_ID_INIT);
}
/**
* get status for load API {#link #loadData(String, String, String)}
* & {#link #loadDataWithBaseURL(String, String, String, String, String)}, set to false.
* <p>
* <b>ignored:</b> {#link #loadUrl(String)}, {#link #loadUrl(String, Map)} and {#link #reload()}
*/
public boolean isLoadDataFinished() {
return loadDataFinished.get();
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
private void handleLoadDataFinished(int what) {
if (loadDataTimestamp.get() == REQUEST_ID_INIT) {
// there is no load data actions
//DLog.w(TAG, "handleLoadDataFinished: there is no load data actions, obj="
// + this.hashCode());
return;
}
DLog.d(TAG, "handleLoadDataFinished: obj=" + this.hashCode());
int delay = 0;
long requestId = loadDataTimestamp.get();
if (what == MSG_LOAD_DATA_FINISH_DEF) {
delay = DELAY_MS_MAX;
} else if (what == MSG_LOAD_DATA_FINISH_DRAW) {
delay = DELAY_MS_DRAW;
}
handler.removeMessages(what);
handler.sendMessageDelayed(Message.obtain(handler, what, (Object) requestId), delay);
}
private void init() {
this.setWebChromeClient(new DefWebChromeClient());
this.setHorizontalScrollBarEnabled(false);
this.setVerticalScrollBarEnabled(false);
this.description = onGetDescription();
}
/**
* a description of this WebView
*/
abstract public String onGetDescription();
#Override
public void loadDataWithBaseURL(
#Nullable String baseUrl, String data, #Nullable String mimeType,
#Nullable String encoding, #Nullable String historyUrl) {
clearLoadDataStatus();
super.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
}
#Override
public void loadData(String data, #Nullable String mimeType, #Nullable String encoding) {
clearLoadDataStatus();
super.loadData(data, mimeType, encoding);
}
#Override
public void stopLoading() {
super.stopLoading();
loadDataFinished();
}
#Override
public void setWebChromeClient(WebChromeClient client) {
if (!(client instanceof DefWebChromeClient)) {
throw new IllegalArgumentException(
"the WebChromeClient must be an instance of " + DefWebChromeClient.class);
}
super.setWebChromeClient(client);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//Log.d(TAG, "onDraw: " + this.hashCode());
if (progressFinished.get()) {
// set load data finished in DELAY_MS_DRAW.
// !!! Notice that the Runnable will not be exec if this WebView is not to show,
// and this will cause the `loadDataFinished` being `false` all the time,
// if you want that executing whatever, plz use `handle.post()`.
post(new Runnable() {
#Override
public void run() {
handleLoadDataFinished(MSG_LOAD_DATA_FINISH_DRAW);
}
});
}
}
class DefWebChromeClient extends WebChromeClient {
#Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if (newProgress == 100) {
progressFinished.set(true);
// set load data finished in DELAY_MS_MAX as def.
// !!! Notice that the Runnable will not be exec if this WebView is not to show,
// and this will cause the `loadDataFinished` being `false` all the time,
// if you want that executing whatever, plz use `handle.post()`.
post(new Runnable() {
#Override
public void run() {
handleLoadDataFinished(MSG_LOAD_DATA_FINISH_DEF);
}
});
}
Log.d(TAG, "onProgressChanged: " + newProgress
+ ", desc=" + description + ", obj=" + view.hashCode());
}
}
static class MyHandler extends Handler {
WeakReference<BaseWebView> mViewReference;
MyHandler(BaseWebView webView) {
mViewReference = new WeakReference<>(webView);
}
#Override
public void handleMessage(Message msg) {
final BaseWebView webView = mViewReference.get();
if (webView == null) {
return;
}
// handle msg
if (msg.what == MSG_LOAD_DATA_FINISH_DEF || msg.what == MSG_LOAD_DATA_FINISH_DRAW) {
webView.setLoadDataFinished((Long) msg.obj);
}
}
}
}
=== END ===
Notice that only loadData() & loadDataWithBaseURL() works above,
you can add loadUrl(), reload() by yourself if needed.
Demo:https://github.com/zhaoya188/completed-load-webview
Related
Currently, I am implementing google Speech to Text in my project. The sample code referred is this: Click Here.
I have used the SpeechService and Voice Recorder class from this project.
public class SpeechService extends Service {
public static final List<String> SCOPE =
Collections.singletonList("https://www.googleapis.com/auth/cloud-platform");
private static final String TAG = "SpeechService";
private static final String PREFS = "SpeechService";
private static final String PREF_ACCESS_TOKEN_VALUE = "access_token_value";
private static final String PREF_ACCESS_TOKEN_EXPIRATION_TIME = "access_token_expiration_time";
/**
* We reuse an access token if its expiration time is longer than this.
*/
private static final int ACCESS_TOKEN_EXPIRATION_TOLERANCE = 30 * 60 * 1000; // thirty minutes
/**
* We refresh the current access token before it expires.
*/
private static final int ACCESS_TOKEN_FETCH_MARGIN = 60 * 1000; // one minute
private static final String HOSTNAME = "speech.googleapis.com";
private static final int PORT = 443;
private static Handler mHandler;
private final SpeechBinder mBinder = new SpeechBinder();
private final ArrayList<Listener> mListeners = new ArrayList<>();
private final StreamObserver<StreamingRecognizeResponse> mResponseObserver
= new StreamObserver<StreamingRecognizeResponse>() {
#Override
public void onNext(StreamingRecognizeResponse response) {
Log.e("Speech", "Recognized");
String text = null;
boolean isFinal = false;
if (response.getResultsCount() > 0) {
System.out.println("result count....."+String.valueOf(response.getResultsCount()));
final StreamingRecognitionResult result = response.getResults(0);
isFinal = result.getIsFinal();
if (result.getAlternativesCount() > 0) {
final SpeechRecognitionAlternative alternative = result.getAlternatives(0);
text = alternative.getTranscript();
}
}
if (text != null && isFinal) {
for (Listener listener : mListeners) {
listener.onSpeechRecognized(text, isFinal);
}
} else {
for (Listener listener : mListeners) {
listener.onRandomStupidity();
}
}
}
#Override
public void onError(Throwable t) {
Log.e(TAG, "Error calling the API.", t);
for(Listener listener : mListeners){
listener.onErrorRecognizing();
}
}
#Override
public void onCompleted() {
Log.i(TAG, "API completed.");
}
};
private volatile AccessTokenTask mAccessTokenTask;
private final Runnable mFetchAccessTokenRunnable = new Runnable() {
#Override
public void run() {
fetchAccessToken();
}
};
private SpeechGrpc.SpeechStub mApi;
private StreamObserver<StreamingRecognizeRequest> mRequestObserver;
public static SpeechService from(IBinder binder) {
return ((SpeechBinder) binder).getService();
}
#Override
public void onCreate() {
super.onCreate();
mHandler = new Handler();
fetchAccessToken();
}
#Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mFetchAccessTokenRunnable);
mHandler = null;
// Release the gRPC channel.
if (mApi != null) {
final ManagedChannel channel = (ManagedChannel) mApi.getChannel();
if (channel != null && !channel.isShutdown()) {
try {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Log.e(TAG, "Error shutting down the gRPC channel.", e);
}
}
mApi = null;
}
}
private void fetchAccessToken() {
if (mAccessTokenTask != null) {
return;
}
mAccessTokenTask = new AccessTokenTask();
mAccessTokenTask.execute();
}
private String getDefaultLanguageCode() {
final LangInnerResponse languageToLearn = MemoryCache.getLanguageToLearn();
if(languageToLearn != null) {
Log.e("Test Lang", languageToLearn.getCode());
return languageToLearn.getCode();
} else {
final Locale locale = Locale.getDefault();
final StringBuilder language = new StringBuilder(locale.getLanguage());
final String country = locale.getCountry();
if (!TextUtils.isEmpty(country)) {
language.append("-");
language.append(country);
}
return language.toString();
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void addListener(#NonNull Listener listener) {
mListeners.add(listener);
}
public void removeListener(#NonNull Listener listener) {
mListeners.remove(listener);
}
/**
** Starts recognizing speech audio.
*
* #param sampleRate The sample rate of the audio.
*/
public void startRecognizing(int sampleRate) {
if (mApi == null) {
Log.w(TAG, "API not ready. Ignoring the request.");
return;
}
System.out.println("calling api....");
// Configure the API
mRequestObserver = mApi.streamingRecognize(mResponseObserver);
mRequestObserver.onNext(StreamingRecognizeRequest.newBuilder()
.setStreamingConfig(StreamingRecognitionConfig.newBuilder()
.setConfig(RecognitionConfig.newBuilder()
.setLanguageCode(getDefaultLanguageCode())
.setEncoding(RecognitionConfig.AudioEncoding.LINEAR16)
.setSampleRateHertz(sampleRate)
.build())
.setInterimResults(true)
.setSingleUtterance(true)
.build())
.build());
}
/**
* Recognizes the speech audio. This method should be called every time a chunk of byte buffer
* is ready.
*
* #param data The audio data.
* #param size The number of elements that are actually relevant in the {#code data}.
*/
public void recognize(byte[] data, int size) {
if (mRequestObserver == null) {
return;
}
// Call the streaming recognition API
mRequestObserver.onNext(StreamingRecognizeRequest.newBuilder()
.setAudioContent(ByteString.copyFrom(data, 0, size))
.build());
}
/**
* Finishes recognizing speech audio.
*/
public void finishRecognizing() {
if (mRequestObserver == null) {
return;
}
mRequestObserver.onCompleted();
mRequestObserver = null;
}
public interface Listener {
/**
* Called when a new piece of text was recognized by the Speech API.
*
* #param text The text.
* #param isFinal {#code true} when the API finished processing audio.
*/
void onSpeechRecognized(String text, boolean isFinal);
void onErrorRecognizing();
void onRandomStupidity();
}
/**
* Authenticates the gRPC channel using the specified {#link GoogleCredentials}.
*/
private static class GoogleCredentialsInterceptor implements ClientInterceptor {
private final Credentials mCredentials;
private Metadata mCached;
private Map<String, List<String>> mLastMetadata;
GoogleCredentialsInterceptor(Credentials credentials) {
mCredentials = credentials;
}
private static Metadata toHeaders(Map<String, List<String>> metadata) {
Metadata headers = new Metadata();
if (metadata != null) {
for (String key : metadata.keySet()) {
Metadata.Key<String> headerKey = Metadata.Key.of(
key, Metadata.ASCII_STRING_MARSHALLER);
for (String value : metadata.get(key)) {
headers.put(headerKey, value);
}
}
}
return headers;
}
#Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
final MethodDescriptor<ReqT, RespT> method, CallOptions callOptions,
final Channel next) {
return new ClientInterceptors.CheckedForwardingClientCall<ReqT, RespT>(
next.newCall(method, callOptions)) {
#Override
protected void checkedStart(Listener<RespT> responseListener, Metadata headers)
throws StatusException {
Metadata cachedSaved;
URI uri = serviceUri(next, method);
synchronized (this) {
Map<String, List<String>> latestMetadata = getRequestMetadata(uri);
if (mLastMetadata == null || mLastMetadata != latestMetadata) {
mLastMetadata = latestMetadata;
mCached = toHeaders(mLastMetadata);
}
cachedSaved = mCached;
}
headers.merge(cachedSaved);
delegate().start(responseListener, headers);
}
};
}
/**
* Generate a JWT-specific service URI. The URI is simply an identifier with enough
* information for a service to know that the JWT was intended for it. The URI will
* commonly be verified with a simple string equality check.
*/
private URI serviceUri(Channel channel, MethodDescriptor<?, ?> method)
throws StatusException {
String authority = channel.authority();
if (authority == null) {
throw Status.UNAUTHENTICATED
.withDescription("Channel has no authority")
.asException();
}
// Always use HTTPS, by definition.
final String scheme = "https";
final int defaultPort = 443;
String path = "/" + MethodDescriptor.extractFullServiceName(method.getFullMethodName());
URI uri;
try {
uri = new URI(scheme, authority, path, null, null);
} catch (URISyntaxException e) {
throw Status.UNAUTHENTICATED
.withDescription("Unable to construct service URI for auth")
.withCause(e).asException();
}
// The default port must not be present. Alternative ports should be present.
if (uri.getPort() == defaultPort) {
uri = removePort(uri);
}
return uri;
}
private URI removePort(URI uri) throws StatusException {
try {
return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), -1 /* port */,
uri.getPath(), uri.getQuery(), uri.getFragment());
} catch (URISyntaxException e) {
throw Status.UNAUTHENTICATED
.withDescription("Unable to construct service URI after removing port")
.withCause(e).asException();
}
}
private Map<String, List<String>> getRequestMetadata(URI uri) throws StatusException {
try {
return mCredentials.getRequestMetadata(uri);
} catch (IOException e) {
throw Status.UNAUTHENTICATED.withCause(e).asException();
}
}
}
private class SpeechBinder extends Binder {
SpeechService getService() {
return SpeechService.this;
}
}
private class CreateApiSingle implements SingleOnSubscribe<SpeechGrpc.SpeechStub> {
#Override
public void subscribe(SingleEmitter<SpeechGrpc.SpeechStub> emitter) throws Exception {
final AccessToken accessToken = generateCredentials();
final SpeechGrpc.SpeechStub api = generateApi(accessToken);
emitter.onSuccess(api);
}
private AccessToken generateCredentials() throws IOException {
final SharedPreferences prefs =
getSharedPreferences(PREFS, Context.MODE_PRIVATE);
String tokenValue = prefs.getString(PREF_ACCESS_TOKEN_VALUE, null);
long expirationTime = prefs.getLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME, -1);
// Check if the current token is still valid for a while
if (tokenValue != null && expirationTime > 0) {
if (expirationTime
> System.currentTimeMillis() + ACCESS_TOKEN_EXPIRATION_TOLERANCE) {
return new AccessToken(tokenValue, new Date(expirationTime));
}
}
// ***** WARNING *****
// In this sample, we load the credential from a JSON file stored in a raw resource
// folder of this client app. You should never do this in your app. Instead, store
// the file in your server and obtain an access token from there.
// *******************
final InputStream stream = getResources().openRawResource(R.raw.credential);
final GoogleCredentials credentials = GoogleCredentials.fromStream(stream)
.createScoped(SCOPE);
final AccessToken token = credentials.refreshAccessToken();
prefs.edit()
.putString(PREF_ACCESS_TOKEN_VALUE, token.getTokenValue())
.putLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME,
token.getExpirationTime().getTime())
.apply();
stream.close();
return token;
}
private SpeechGrpc.SpeechStub generateApi(AccessToken accessToken) {
final ManagedChannel channel = new OkHttpChannelProvider()
.builderForAddress(HOSTNAME, PORT)
.nameResolverFactory(new DnsNameResolverProvider())
.intercept(new GoogleCredentialsInterceptor(new GoogleCredentials(accessToken)
.createScoped(SCOPE)))
.build();
return SpeechGrpc.newStub(channel);
}
}
private class AccessTokenTask extends AsyncTask<Void, Void, AccessToken> {
#Override
protected AccessToken doInBackground(Void... voids) {
final SharedPreferences prefs =
getSharedPreferences(PREFS, Context.MODE_PRIVATE);
String tokenValue = prefs.getString(PREF_ACCESS_TOKEN_VALUE, null);
long expirationTime = prefs.getLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME, -1);
// Check if the current token is still valid for a while
if (tokenValue != null && expirationTime > 0) {
if (expirationTime
> System.currentTimeMillis() + ACCESS_TOKEN_EXPIRATION_TOLERANCE) {
return new AccessToken(tokenValue, new Date(expirationTime));
}
}
// ***** WARNING *****
// In this sample, we load the credential from a JSON file stored in a raw resource
// folder of this client app. You should never do this in your app. Instead, store
// the file in your server and obtain an access token from there.
// *******************
final InputStream stream = getResources().openRawResource(R.raw.credential);
try {
final GoogleCredentials credentials = GoogleCredentials.fromStream(stream)
.createScoped(SCOPE);
final AccessToken token = credentials.refreshAccessToken();
prefs.edit()
.putString(PREF_ACCESS_TOKEN_VALUE, token.getTokenValue())
.putLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME,
token.getExpirationTime().getTime())
.apply();
return token;
} catch (IOException e) {
Log.e(TAG, "Failed to obtain access token.", e);
}
return null;
}
#Override
protected void onPostExecute(AccessToken accessToken) {
mAccessTokenTask = null;
final ManagedChannel channel = new OkHttpChannelProvider()
.builderForAddress(HOSTNAME, PORT)
.nameResolverFactory(new DnsNameResolverProvider())
.intercept(new GoogleCredentialsInterceptor(new GoogleCredentials(accessToken)
.createScoped(SCOPE)))
.build();
mApi = SpeechGrpc.newStub(channel);
// Schedule access token refresh before it expires
if (mHandler != null) {
mHandler.postDelayed(mFetchAccessTokenRunnable,
Math.max(accessToken.getExpirationTime().getTime()
- System.currentTimeMillis()
- ACCESS_TOKEN_FETCH_MARGIN, ACCESS_TOKEN_EXPIRATION_TOLERANCE));
}
}
}}
public class VoiceRecorder {
private static final int[] SAMPLE_RATE_CANDIDATES = new int[]{48000, 44100};
private static final int CHANNEL = AudioFormat.CHANNEL_IN_MONO;
private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private static final int AMPLITUDE_THRESHOLD = 1500;
private static final int SPEECH_TIMEOUT_MILLIS = 2000;
private static final int MAX_SPEECH_LENGTH_MILLIS = 30 * 1000;
public static abstract class Callback {
/**
* Called when the recorder starts hearing voice.
*/
public void onVoiceStart() {
}
/**
* Called when the recorder is hearing voice.
*
* #param data The audio data in {#link AudioFormat#ENCODING_PCM_16BIT}.
* #param size The size of the actual data in {#code data}.
*/
public void onVoice(byte[] data, int size) {
}
/**
* Called when the recorder stops hearing voice.
*/
public void onVoiceEnd() {
}
}
private final Callback mCallback;
private AudioRecord mAudioRecord;
private Thread mThread;
private byte[] mBuffer;
private final Object mLock = new Object();
/** The timestamp of the last time that voice is heard. */
private long mLastVoiceHeardMillis = Long.MAX_VALUE;
/** The timestamp when the current voice is started. */
private long mVoiceStartedMillis;
public VoiceRecorder(#NonNull Callback callback) {
mCallback = callback;
}
/**
* Starts recording audio.
*
* <p>The caller is responsible for calling {#link #stop()} later.</p>
*/
public void start() {
// Stop recording if it is currently ongoing.
stop();
// Try to create a new recording session.
mAudioRecord = createAudioRecord();
if (mAudioRecord == null) {
throw new RuntimeException("Cannot instantiate VoiceRecorder");
}
// Start recording.
mAudioRecord.startRecording();
// Start processing the captured audio.
mThread = new Thread(new ProcessVoice());
mThread.start();
}
/**
* Stops recording audio.
*/
public void stop() {
synchronized (mLock) {
System.out.println("stop audio record....");
dismiss();
if (mThread != null) {
mThread.interrupt();
mThread = null;
}
if (mAudioRecord != null) {
mAudioRecord.stop();
mAudioRecord.release();
mAudioRecord = null;
}
mBuffer = null;
System.out.println("stop audio record....2");
}
}
/**
* Dismisses the currently ongoing utterance.
*/
public void dismiss() {
if (mLastVoiceHeardMillis != Long.MAX_VALUE) {
mLastVoiceHeardMillis = Long.MAX_VALUE;
mCallback.onVoiceEnd();
}
}
/**
* Retrieves the sample rate currently used to record audio.
*
* #return The sample rate of recorded audio.
*/
public int getSampleRate() {
if (mAudioRecord != null) {
return mAudioRecord.getSampleRate();
}
return 0;
}
/**
* Creates a new {#link AudioRecord}.
*
* #return A newly created {#link AudioRecord}, or null if it cannot be created (missing
* permissions?).
*/
private AudioRecord createAudioRecord() {
for (int sampleRate : SAMPLE_RATE_CANDIDATES) {
final int sizeInBytes = AudioRecord.getMinBufferSize(sampleRate, CHANNEL, ENCODING);
if (sizeInBytes == AudioRecord.ERROR_BAD_VALUE) {
continue;
}
final AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, CHANNEL, ENCODING, sizeInBytes);
if (audioRecord.getState() == AudioRecord.STATE_INITIALIZED) {
mBuffer = new byte[sizeInBytes];
return audioRecord;
} else {
audioRecord.release();
}
}
return null;
}
/**
* Continuously processes the captured audio and notifies {#link #mCallback} of corresponding
* events.
*/
private class ProcessVoice implements Runnable {
#Override
public void run() {
while (true) {
synchronized (mLock) {
if (Thread.currentThread().isInterrupted()) {
break;
}
final int size = mAudioRecord.read(mBuffer, 0, mBuffer.length);
final long now = System.currentTimeMillis();
if (isHearingVoice(mBuffer, size)) {
if (mLastVoiceHeardMillis == Long.MAX_VALUE) {
mVoiceStartedMillis = now;
mCallback.onVoiceStart();
}
mCallback.onVoice(mBuffer, size);
mLastVoiceHeardMillis = now;
if (now - mVoiceStartedMillis > MAX_SPEECH_LENGTH_MILLIS) {
end();
}
} else if (mLastVoiceHeardMillis != Long.MAX_VALUE) {
mCallback.onVoice(mBuffer, size);
if (now - mLastVoiceHeardMillis > SPEECH_TIMEOUT_MILLIS) {
end();
}
}
}
}
}
private void end() {
mLastVoiceHeardMillis = Long.MAX_VALUE;
mCallback.onVoiceEnd();
System.out.println("end...");
}
private boolean isHearingVoice(byte[] buffer, int size) {
for (int i = 0; i < size - 1; i += 2) {
// The buffer has LINEAR16 in little endian.
int s = buffer[i + 1];
if (s < 0) s *= -1;
s <<= 8;
s += Math.abs(buffer[i]);
if (s > AMPLITUDE_THRESHOLD) {
return true;
}
}
return false;
}
}}
Then I implemented the Speech Service & Voice Recorder callback as follows:
private VoiceRecorder voiceRecorder;
private final SpeechService.Listener speechServiceListener = new SpeechService.Listener() {
#Override
public void onSpeechRecognized(final String text, final boolean isFinal) {
if (isFinal) {
System.out.println("ui thread...");
if (!TextUtils.isEmpty(text)) {
runOnUiThread(() -> {
showMessage(text);
flingAnswer(text);
});
}
}
}
#Override
public void onErrorRecognizing() {
showMessage("Please try again. Could not detect.");
}
#Override
public void onRandomStupidity() {
}
};
private SpeechService speechService;
private final VoiceRecorder.Callback voiceCallback = new VoiceRecorder.Callback() {
#Override
public void onVoiceStart() {
if (speechService != null) {
System.out.println("voice start....");
speechService.startRecognizing(voiceRecorder.getSampleRate());
}
}
#Override
public void onVoice(byte[] data, int size) {
if (speechService != null) {
speechService.recognize(data, size);
}
}
#Override
public void onVoiceEnd() {
if (speechService != null) {
speechService.finishRecognizing();
}
}
};
private final ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder binder) {
speechService = SpeechService.from(binder);
speechService.addListener(speechServiceListener);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
speechService = null;
}
};
For voice input this is the code:
#Override
public void stopRecognizing() {
stopVoiceRecorder();
Log.e("Recording", "Stopped");
}
#Override
public void startRecognizing() {
if (permissionManager != null && permissionManager.askForPermissions()) {
startVoiceRecorder();
vibrate.vibrate(50);//Providing haptic feedback to user on press.
}
Log.e("Recording", "Started");
}
binding.imgVoice.setOnTouchListener((v, event) -> {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
System.out.println("up...");
mCallback.stopRecognizing();
binding.imgVoice
.animate()
.scaleX(1.0f)
.scaleY(1.0f);
binding.imgVoice.setVisibility(View.GONE);
binding.progressBar.setVisibility(View.VISIBLE);
break;
case MotionEvent.ACTION_DOWN:
System.out.println("down...");
binding.imgVoice
.animate()
.scaleX(1.8f)
.scaleY(1.8f);
mCallback.startRecognizing();
break;
}
return true;
});
}
When I press the mic, event registered as Action_Down, I start the voice recorder and on releasing the mic , voice recorder is stopped. Also, with the Action_Down I am scaling up the mic icon which needs to be scaled down on Action_Up . But the ui freezes as a whole most of the times. I find that the onNext() callback for StreamObserver is continuously being invoked before the isFinal becomes true.
private void startVoiceRecorder() {
if (voiceRecorder != null) {
voiceRecorder.stop();
}
voiceRecorder = new VoiceRecorder(voiceCallback);
voiceRecorder.start();
}
private void stopVoiceRecorder() {
if (voiceRecorder != null) {
voiceRecorder.stop();
voiceRecorder = null;
}
}
But I want the mic to scale down as soon as I release the mic(on Action up event) which is not happening.
So if anyone can help me over this?
Thanks in Advance.
I have a project: myApp
these files...
- myFragment.java.
- myDialogFragment.java.
- myAsyncTask.java
I have a project: myLibrary
This project "is Library" of "myApp"
I have...
- myMethodsToUpload.java
One of these methods, have a While bucle for write the file on php server.
Everything works like magic! :)
and the reason for the file structure is to make the library reusable.
but...
How can I send the increments of a value inside of this While bucle, to myAsyncTask.java?
Considering that...
what I want to do... is to make "myMethodsToUpload.java", reusable.
Some code...
myFragment.java
myDialogFragment df = new myDialogFragment();
df.setMyThings(new myAsynctask(), myParameters);
df.setTargetFragment(this, 0);
df.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
.
myDialogFragment.java
public class myDialogFragment extends DialogFragment {
myAsyncTask async;
public void setMyThings(myAsynctask inAsynctask, String[] inArray){
async = inAsynctask;
async.sendFragment(this);
parameters = inArray;
}
//...
//Only called from "myAsyncTask.java"
public void updateFromAsyncTask(Integer porcent){
progressbar.setProgress(porcent);
}
//...
}
.
myAsyncTask.java
public class myAsynctask extends AsyncTask<String, Integer, String> {
void sendFragment(myDialogFrament inFragment){
myDialogFrament = inFragment;
}
//...
#Override
protected String doInBackground(String... inArray) {
String urlPHP = inArray[0];
String pathImg = inArray[1];
String paramValue = inArray[2];
String msj = "";
try {
methodsToUpload up = new methodsToUpload(urlPHP);
up.connectNow();
up.insertFile(pathImg);
up.insertParams("pName", paramValue);
up.insertFinish();
msj = up.coonectClose();
} catch (Exception e) {
e.printStackTrace();
}
return msj;
}
//Called from "myMethods.java"
public void updateFromAsyncTask(int porcent){
publishProgress(porcent);
}
#Override
protected void onProgressUpdate(Integer... inPorcent) {
if(myDialogFragment == null){
return;
}
myDialogFragment.updateFromAsyncTask(inPorcent[0]);
}
}
.
myMethodsToUpload.java
public class myMethodsToUpload {
//...
public myMethodsToUpload(String url_in){
this.url = url_in;
}
public void insertFile(String path) throws Exception {
//...
//...
while (bytesRead > 0) {
salidaStream.write(buffer, 0, bufferSize);
sendedPorcent += bytesRead;
completedPorcent = (int) (sendedPorcent * 100 / fileSize);
//This line doesn't work...
//because myAsyncTask.java, is in another project.
myAsyncTask.updateFromAsyncTask(completedPorcent);
bytesAvailable = archivoStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = archivoStream.read(buffer, 0, bufferSize);
}
//...
//...
}
}
.
I've already tried...
"MyLibrary" -> propeties -> java build path -> projects -> add -> Project(myApp)
but...
throws me errors:
W/System.err(32469): at java.util.concurrent.FutureTask.run(FutureTask.java:237)...
ThreadPoolExecutor.runworker...
etc.
And, in the status bar of eclipse appears every moment "Building Workspace (X%)"
I'm a newbie, but I think the error happens because "MyLibrary" is Library of "MyApp", and I'm trying use "java build path".
So... how can I resolve this?, I'm lost!!!
sorry by my english... thanks in advance! :)
Here is a simple exemple :
Your AsyncTask class :
private CallBack mCallback;
public static interface CallBack {
public void updateValue(int value);
}
public void setCallBack(CallBack callBack){
this.mCallBack = callBack;
}
#Override
protected void onProgressUpdate(Integer... inPorcent) {
mCallback.updateValue(inPorcent[0].intValue());
}
Your fragment class :
public class Fragment extends Fragment implements Callback {
private AsyncTask yourAsyncTask;
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
yourAsyncTask = new AsyncTask();
yourAsyncTask.setCallBack(this);
yourAsyncTask.excecute();
}
#Override
public void updateValue(int value){
Log.e(TAG,"Value : " + value);
}
}
EDIT 1 :
public class AdsHttpRequest {
private static final String TAG = AdsHttpRequest.class.getSimpleName(); // log
private GetHttpTask mGetAsyncTask;
private static AdsHttpRequest mInstance;
private OnGetRequestListener mCallBack;
private static final String SUCCESS = "success";
private static final String SUCCES = "succes";
private static final String FAILED = "fail";
/**
* #return a singleton instance of {#link AdsHttpRequest}
*/
public static AdsHttpRequest getInstance() {
if (mInstance == null) {
synchronized (AdsHttpRequest.class) {
if (mInstance == null) {
mInstance = new AdsHttpRequest();
}
}
}
return mInstance;
}
/**
* Initialize the {#link AsyncTask}, set the callback, execute the task
*
* #param url
* url for the request
* #param callback
* {#link OnGetRequestListener} for feed back
*/
public void post(String url, OnGetRequestListener callback) {
mCallBack = callback;
if (mGetAsyncTask == null) {
mGetAsyncTask = new GetHttpTask();
} else {
cancelGetTask();
mGetAsyncTask = new GetHttpTask();
}
mGetAsyncTask.execute(url);
}
/**
* cancel the {#link AsyncTask} if it's still alive <br>
* <b>see </b> {#link Status}
*/
public void cancelGetTask() {
if (mGetAsyncTask != null && mGetAsyncTask.getStatus().equals(Status.RUNNING)) {
mGetAsyncTask.cancel(true);
}
mGetAsyncTask = null;
}
private AdsHttpRequest() {
super();
}
/**
* Actually construct and launch the HTTP request
*
* #param url
* url of the request
* #return response of the server
*/
private String getResponseFromUrl(String url) {
String xml = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (Exception e) {
Log.e(TAG, "", e);
}
return xml;
}
/**
* Manage the http request in background
*
* #param String
* url for the request
*/
private class GetHttpTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
if (params[0] != null) {
return getResponseFromUrl(params[0]); // return the response of the server
}
return null;
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
if (result.contains(SUCCES) || result.contains(SUCCESS)) {
mCallBack.onGetRequestResult(SUCCESS);
} else {
mCallBack.onGetRequestResult(FAILED);
}
}
}
}
}
The way that I'm doing this consume more memory, time, threads? (I'm guessing)
I am working on barcode scanning on button click to increment the quantity counted field by one of a table when the scanning result matches with the item number field of the table. If the scan result matches item number it should update the quantity counted of that row. I am unable to get the scan result itself. Getting NullPointerException.
This is my code.
These are two Java files from zxing.
IntentIntegrator.java
package com.example.mis;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
public class IntentIntegrator {
public static final int REQUEST_CODE = 0x0000c0de; // Only use bottom 16
// bits
private static final String TAG = IntentIntegrator.class.getSimpleName();
public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
public static final String DEFAULT_MESSAGE = "This application requires Barcode Scanner. Would you like to install it?";
public static final String DEFAULT_YES = "Yes";
public static final String DEFAULT_NO = "No";
private static final String BS_PACKAGE = "com.google.zxing.client.android";
private static final String BSPLUS_PACKAGE = "com.srowen.bs.android";
// supported barcode formats
public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A",
"UPC_E", "EAN_8", "EAN_13", "RSS_14");
public static final Collection<String> ONE_D_CODE_TYPES = list("UPC_A",
"UPC_E", "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128",
"ITF", "RSS_14", "RSS_EXPANDED");
public static final Collection<String> QR_CODE_TYPES = Collections
.singleton("QR_CODE");
public static final Collection<String> DATA_MATRIX_TYPES = Collections
.singleton("DATA_MATRIX");
public static final Collection<String> ALL_CODE_TYPES = null;
public static final List<String> TARGET_BARCODE_SCANNER_ONLY = Collections
.singletonList(BS_PACKAGE);
public static final List<String> TARGET_ALL_KNOWN = list(BSPLUS_PACKAGE, // Barcode
// Scanner+
BSPLUS_PACKAGE + ".simple", // Barcode Scanner+ Simple
BS_PACKAGE // Barcode Scanner
// What else supports this intent?
);
private final Activity activity;
private String title;
private String message;
private String buttonYes;
private String buttonNo;
private List<String> targetApplications;
private final Map<String, Object> moreExtras;
public IntentIntegrator(Activity activity) {
this.activity = activity;
title = DEFAULT_TITLE;
message = DEFAULT_MESSAGE;
buttonYes = DEFAULT_YES;
buttonNo = DEFAULT_NO;
targetApplications = TARGET_ALL_KNOWN;
moreExtras = new HashMap<String, Object>(3);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public void setTitleByID(int titleID) {
title = activity.getString(titleID);
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setMessageByID(int messageID) {
message = activity.getString(messageID);
}
public String getButtonYes() {
return buttonYes;
}
public void setButtonYes(String buttonYes) {
this.buttonYes = buttonYes;
}
public void setButtonYesByID(int buttonYesID) {
buttonYes = activity.getString(buttonYesID);
}
public String getButtonNo() {
return buttonNo;
}
public void setButtonNo(String buttonNo) {
this.buttonNo = buttonNo;
}
public void setButtonNoByID(int buttonNoID) {
buttonNo = activity.getString(buttonNoID);
}
public Collection<String> getTargetApplications() {
return targetApplications;
}
public final void setTargetApplications(List<String> targetApplications) {
if (targetApplications.isEmpty()) {
throw new IllegalArgumentException("No target applications");
}
this.targetApplications = targetApplications;
}
public void setSingleTargetApplication(String targetApplication) {
this.targetApplications = Collections.singletonList(targetApplication);
}
public Map<String, ?> getMoreExtras() {
return moreExtras;
}
public final void addExtra(String key, Object value) {
moreExtras.put(key, value);
}
/**
* Initiates a scan for all known barcode types.
*/
public final AlertDialog initiateScan() {
return initiateScan(ALL_CODE_TYPES);
}
/**
* Initiates a scan only for a certain set of barcode types, given as
* strings corresponding to their names in ZXing's {#code BarcodeFormat}
* class like "UPC_A". You can supply constants like
* {#link #PRODUCT_CODE_TYPES} for example.
*
* #return the {#link AlertDialog} that was shown to the user prompting them
* to download the app if a prompt was needed, or null otherwise
*/
public final AlertDialog initiateScan(
Collection<String> desiredBarcodeFormats) {
Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
// check which types of codes to scan for
if (desiredBarcodeFormats != null) {
// set the desired barcode types
StringBuilder joinedByComma = new StringBuilder();
for (String format : desiredBarcodeFormats) {
if (joinedByComma.length() > 0) {
joinedByComma.append(',');
}
joinedByComma.append(format);
}
intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
}
String targetAppPackage = findTargetAppPackage(intentScan);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intentScan.setPackage(targetAppPackage);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intentScan);
startActivityForResult(intentScan, REQUEST_CODE);
return null;
}
/**
* Start an activity. This method is defined to allow different methods of
* activity starting for newer versions of Android and for compatibility
* library.
*
* #param intent
* Intent to start.
* #param code
* Request code for the activity
* #see android.app.Activity#startActivityForResult(Intent, int)
* #see android.app.Fragment#startActivityForResult(Intent, int)
*/
protected void startActivityForResult(Intent intent, int code) {
activity.startActivityForResult(intent, code);
}
private String findTargetAppPackage(Intent intent) {
PackageManager pm = activity.getPackageManager();
List<ResolveInfo> availableApps = pm.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
if (availableApps != null) {
for (String targetApp : targetApplications) {
if (contains(availableApps, targetApp)) {
return targetApp;
}
}
}
return null;
}
private static boolean contains(Iterable<ResolveInfo> availableApps,
String targetApp) {
for (ResolveInfo availableApp : availableApps) {
String packageName = availableApp.activityInfo.packageName;
if (targetApp.equals(packageName)) {
return true;
}
}
return false;
}
private AlertDialog showDownloadDialog() {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
downloadDialog.setTitle(title);
downloadDialog.setMessage(message);
downloadDialog.setPositiveButton(buttonYes,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String packageName = targetApplications.get(0);
Uri uri = Uri.parse("market://details?id="
+ packageName);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try {
activity.startActivity(intent);
} catch (ActivityNotFoundException anfe) {
// Hmm, market is not installed
Log.w(TAG,
"Google Play is not installed; cannot install "
+ packageName);
}
}
});
downloadDialog.setNegativeButton(buttonNo,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
return downloadDialog.show();
}
/**
* <p>
* Call this from your {#link Activity}'s
* {#link Activity#onActivityResult(int, int, Intent)} method.
* </p>
*
* #return null if the event handled here was not related to this class, or
* else an {#link IntentResult} containing the result of the scan.
* If the user cancelled scanning, the fields will be null.
*/
public static IntentResult parseActivityResult(int requestCode,
int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
String contents = intent.getStringExtra("SCAN_RESULT");
String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
byte[] rawBytes = intent.getByteArrayExtra("SCAN_RESULT_BYTES");
int intentOrientation = intent.getIntExtra(
"SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
Integer orientation = intentOrientation == Integer.MIN_VALUE ? null
: intentOrientation;
String errorCorrectionLevel = intent
.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");
return new IntentResult(contents, formatName, rawBytes,
orientation, errorCorrectionLevel);
}
return new IntentResult();
}
return null;
}
/**
* Defaults to type "TEXT_TYPE".
*
* #see #shareText(CharSequence, CharSequence)
*/
public final AlertDialog shareText(CharSequence text) {
return shareText(text, "TEXT_TYPE");
}
/**
* Shares the given text by encoding it as a barcode, such that another user
* can scan the text off the screen of the device.
*
* #param text
* the text string to encode as a barcode
* #param type
* type of data to encode. See
* {#code com.google.zxing.client.android.Contents.Type}
* constants.
* #return the {#link AlertDialog} that was shown to the user prompting them
* to download the app if a prompt was needed, or null otherwise
*/
public final AlertDialog shareText(CharSequence text, CharSequence type) {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction(BS_PACKAGE + ".ENCODE");
intent.putExtra("ENCODE_TYPE", type);
intent.putExtra("ENCODE_DATA", text);
String targetAppPackage = findTargetAppPackage(intent);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intent.setPackage(targetAppPackage);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intent);
activity.startActivity(intent);
return null;
}
private static List<String> list(String... values) {
return Collections.unmodifiableList(Arrays.asList(values));
}
private void attachMoreExtras(Intent intent) {
for (Map.Entry<String, Object> entry : moreExtras.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Kind of hacky
if (value instanceof Integer) {
intent.putExtra(key, (Integer) value);
} else if (value instanceof Long) {
intent.putExtra(key, (Long) value);
} else if (value instanceof Boolean) {
intent.putExtra(key, (Boolean) value);
} else if (value instanceof Double) {
intent.putExtra(key, (Double) value);
} else if (value instanceof Float) {
intent.putExtra(key, (Float) value);
} else if (value instanceof Bundle) {
intent.putExtra(key, (Bundle) value);
} else {
intent.putExtra(key, value.toString());
}
}
}
}
IntentResult.java
package com.example.mis;
public class IntentResult {
private final String contents;
private final String formatName;
private final byte[] rawBytes;
private final Integer orientation;
private final String errorCorrectionLevel;
IntentResult() {
this(null, null, null, null, null);
}
IntentResult(String contents,
String formatName,
byte[] rawBytes,
Integer orientation,
String errorCorrectionLevel) {
this.contents = contents;
this.formatName = formatName;
this.rawBytes = rawBytes;
this.orientation = orientation;
this.errorCorrectionLevel = errorCorrectionLevel;
}
/**
* #return raw content of barcode
*/
public String getContents() {
return contents;
}
/**
* #return name of format, like "QR_CODE", "UPC_A". See {#code BarcodeFormat} for more format names.
*/
public String getFormatName() {
return formatName;
}
/**
* #return raw bytes of the barcode content, if applicable, or null otherwise
*/
public byte[] getRawBytes() {
return rawBytes;
}
/**
* #return rotation of the image, in degrees, which resulted in a successful scan. May be null.
*/
public Integer getOrientation() {
return orientation;
}
/**
* #return name of the error correction level used in the barcode, if applicable
*/
public String getErrorCorrectionLevel() {
return errorCorrectionLevel;
}
#Override
public String toString() {
StringBuilder dialogText = new StringBuilder(100);
dialogText.append("Format: ").append(formatName).append('\n');
dialogText.append("Contents: ").append(contents).append('\n');
int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
dialogText.append("Raw bytes: (").append(rawBytesLength).append(" bytes)\n");
dialogText.append("Orientation: ").append(orientation).append('\n');
dialogText.append("EC level: ").append(errorCorrectionLevel).append('\n');
return dialogText.toString();
}
}
This is the activity in which i am implementing barcode scanning
public class InventoryCount extends Activity {
private Button mbtn_scan;
mbtn_scan.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
IntentIntegrator integrator = new IntentIntegrator(
InventoryCount.this);
integrator.initiateScan();
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
// retrieve result of scanning - instantiate ZXing object
IntentResult scanningResult = IntentIntegrator.parseActivityResult(
requestCode, resultCode, intent);
// check we have a valid result
try {
if (resultCode == RESULT_OK) {
Log.i("Scanning Result ", "" + scanningResult);
Toast.makeText(
InventoryCount.this,
"Scanning success the content is : "
+ scanningResult.getContents(),
Toast.LENGTH_SHORT).show();
String sr = scanningResult.getContents();
getBarCodeData(sr);
} else if (resultCode == RESULT_CANCELED) {
Toast toast = Toast.makeText(InventoryCount.this,
"Scanning Cancelled!", Toast.LENGTH_SHORT);
toast.show();
}
} catch (Exception e) {
System.out.println("Error on scanning: "+e);
}
}
public void getBarCodeData(String itmNumber) {
Cursor c;
try {
String qtyCountQry = "SELECT " + DatabaseHandler.KEY_QTYCOUNTED
+ " FROM " + DatabaseHandler.TABLE_MIC2 + " WHERE "
+ DatabaseHandler.KEY_ITEMNUMBER + "='" + itmNumber + "'";
SQLiteDatabase sq = db.getReadableDatabase();
c = sq.rawQuery(qtyCountQry, null);
c.moveToFirst();
String q2 = c.getString(c
.getColumnIndex(DatabaseHandler.KEY_QTYCOUNTED));
Toast.makeText(InventoryCount.this, "Quantity Count is " + q2,
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(InventoryCount.this, "Exception " + e,
Toast.LENGTH_SHORT).show();
}
}
I have just tried to display scan result and if it matches itemnumber it will display the corresponding quantity in that row as shown in code above. But as of now not even scan result is displaying. Help me.. Also say how to increment the quantity by one and update it in db.
Try to use the zxing library by extending the CaptureActivity Class.
public class ScannerData extends CaptureActivity {
Handler handler = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_scanner);
}
#Override
public void handleDecode(final Result rawResult, Bitmap barcode,
float scaleFactor) {
// TODO Auto-generated method stub
handler = getHandler();
handler.sendEmptyMessageDelayed(R.id.restart_preview,
CaptureActivity.BULK_MODE_SCAN_DELAY_MS);
String mQrcode = rawResult.getText().toString();
}
}
Use the code like this.
You can get the qr-code here
String mQrcode = rawResult.getText().toString();
In Xml you need to include capture.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/frameLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_horizontal"
android:layout_marginRight="25dp">
<FrameLayout
android:layout_width="510dp"
android:layout_height="310dp"
android:background="#drawable/scanner_box"
android:layout_gravity="center" >
<include
android:layout_width="750dp"
android:layout_height="450dp"
android:layout_gravity="center"
android:layout_marginBottom="50dp"
android:layout_marginRight="110dp"
layout="#layout/capture" />
</FrameLayout>
</RelativeLayout>
</RelativeLayout>
have a gridView populated by bitmaps that animate in when the bitmap loads asynchronously.
Sometimes when flinging the gridView some of the items do not render properly. The animation will trigger but the bitmap will simply not show up.
I have confirmed that the bitmap is indeed there (at least the data) but it just doesn't render.
This happens when flinging the gridView quickly but also happens on a slow scroll as well.
It seems that the view recycling is not working properly.
Here is my code:
ListView adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if(convertView == null){
convertView = new FlipAnimatedCacheableImage(mContext);
}
final ImageInfo info = mapItem(getItem(position));
FlipAnimatedCacheableImage image = (FlipAnimatedCacheableImage)convertView;
image.resetState();
image.setTitle(info.title);
image.setSubTitle(info.subTitle);
image.loadImage(info.imgURL, false);
return convertView;
}
Code for FlipAnimatedCacheableImage:
public class FlipAnimatedCacheableImage extends FrameLayout
{
private static final String TAG = FlipAnimatedCacheableImage.class.getCanonicalName();
protected static final long DURATION = 300;
private ImageView mPlaceHolder;
private NetworkedCacheableImageView mCacheableImage;
private View mTextContainer;
private TextView mTitleTv;
private TextView mSubTitleTv;
private View mProgress;
private ImageLoadListener mListener = new ImageLoadListener()
{
private boolean isShown;
#Override
public void onImageLoaded(boolean animate)
{
if(animate){
mProgress.setVisibility(View.GONE);
mPlaceHolder.setVisibility(View.VISIBLE);
mPlaceHolder.setRotationY(0);
mCacheableImage.setVisibility(View.VISIBLE);
mCacheableImage.setRotationY(-90);
mPlaceHolder.animate().rotationY(90).setDuration(DURATION).start();
mCacheableImage.animate().rotationY(0).setDuration(DURATION).setStartDelay(DURATION).start();
if(!TextUtils.isEmpty(mTitleTv.getText()) || !TextUtils.isEmpty(mSubTitleTv.getText())){
mTextContainer.setVisibility(View.VISIBLE);
mTextContainer.setAlpha(0);
mTextContainer.animate().alpha(1).setDuration(DURATION).setStartDelay(DURATION * 2).start();
}
else{
mTextContainer.setVisibility(View.GONE);
}
isShown = true;
FlipAnimatedCacheableImage.this.invalidate();
}
else{
mPlaceHolder.setVisibility(View.GONE);
mProgress.setVisibility(View.GONE);
mCacheableImage.setVisibility(View.VISIBLE);
mCacheableImage.setRotationY(0);
mCacheableImage.clearAnimation();
if(!TextUtils.isEmpty(mTitleTv.getText()) || !TextUtils.isEmpty(mSubTitleTv.getText())){
mTextContainer.setVisibility(View.VISIBLE);
mTextContainer.setAlpha(1);
}
else{
mTextContainer.setVisibility(View.GONE);
}
FlipAnimatedCacheableImage.this.invalidate();
}
}
};
public FlipAnimatedCacheableImage(Context context, boolean isLarge)
{
this(context, null, 0, isLarge);
}
public FlipAnimatedCacheableImage(Context context)
{
this(context, null);
}
public FlipAnimatedCacheableImage(Context context, AttributeSet attrs)
{
this(context, attrs, 0, false);
}
public FlipAnimatedCacheableImage(Context context, AttributeSet attrs, int defStyle, boolean isLarge)
{
super(context, attrs, defStyle);
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.item_image_thumbnail, this);
mCacheableImage = (NetworkedCacheableImageView)this.findViewById(R.id.image_view);
mPlaceHolder = (ImageView)this.findViewById(R.id.place_holder);
mProgress = this.findViewById(R.id.progressBar);
// only used by small images
mTextContainer = this.findViewById(R.id.text_container);
mTitleTv = (TextView)this.findViewById(R.id.text_title);
mSubTitleTv = (TextView)this.findViewById(R.id.text_sub_title);
// listener to animate after loading
mCacheableImage.setLoadListener(mListener);
// set default state
mTextContainer.setVisibility(View.GONE);
mTitleTv.setVisibility(GONE);
mSubTitleTv.setVisibility(GONE);
if(isLarge){
// adjust the size to the correct dimensions, ignore titleAnd subTitle
FrameLayout.LayoutParams imageParams = new FrameLayout.LayoutParams((int)context.getResources()
.getDimension(R.dimen.grid_image_width_large), (int)context.getResources().getDimension(
R.dimen.grid_image_height_large));
findViewById(R.id.content_wrapper).setLayoutParams(imageParams);
}
// this.setOnClickListener(listener);
resetState();
}
public void resetState()
{
mCacheableImage.setVisibility(View.VISIBLE);
mCacheableImage.setRotationY(0);
mProgress.setVisibility(View.VISIBLE);
mPlaceHolder.setVisibility(View.VISIBLE);
mTextContainer.setVisibility(View.GONE);
mTitleTv.setVisibility(GONE);
mSubTitleTv.setVisibility(GONE);
}
public boolean loadImage(String url, boolean fullSize)
{
return mCacheableImage.loadImage(url, fullSize);
}
public void setTitle(String title)
{
mTitleTv.setText(title);
if(!TextUtils.isEmpty(title)){
mTitleTv.setVisibility(View.VISIBLE);
}
else{
mTitleTv.setVisibility(View.GONE);
}
}
public void setSubTitle(String subTitle)
{
mSubTitleTv.setText(subTitle);
if(!TextUtils.isEmpty(subTitle)){
mSubTitleTv.setVisibility(View.VISIBLE);
}
else{
mSubTitleTv.setVisibility(View.GONE);
}
}
}
FlipAnimatedCache will request the image from a cache written by Chris Banes here https://github.com/chrisbanes/Android-BitmapCache
Here is that code:
/*******************************************************************************
* Copyright 2011, 2013 Chris Banes.
*
* 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.
*******************************************************************************/
/**
* Simple extension of CacheableImageView which allows downloading of Images of
* the Internet.
*
* This code isn't production quality, but works well enough for this sample.s
*
* #author Chris Banes
*
*/
public class NetworkedCacheableImageView extends CacheableImageView
{
private static final String TAG = NetworkedCacheableImageView.class.getCanonicalName();
public interface ImageLoadListener
{
public void onImageLoaded(boolean animate);
}
/**
* This task simply fetches an Bitmap from the specified URL and wraps it in
* a wrapper. This implementation is NOT 'best practice' or production ready
* code.
*/
private static class ImageUrlAsyncTask extends AsyncTask<String, Void, CacheableBitmapDrawable>
{
private final BitmapLruCache mCache;
private final WeakReference<ImageView> mImageViewRef;
private final WeakReference<NetworkedCacheableImageView> viewRef;
private final BitmapFactory.Options mDecodeOpts;
private final ImageLoadListener mLoadListener;
private boolean outOfMemoryFailure;
private String mURL;
ImageUrlAsyncTask(ImageView imageView, BitmapLruCache cache, BitmapFactory.Options decodeOpts,
ImageLoadListener listener, NetworkedCacheableImageView view)
{
mCache = cache;
mLoadListener = listener;
mImageViewRef = new WeakReference<ImageView>(imageView);
viewRef = new WeakReference<NetworkedCacheableImageView>(view);
mDecodeOpts = decodeOpts;
}
#Override
protected CacheableBitmapDrawable doInBackground(String... params)
{
try{
// Return early if the ImageView has disappeared.
if(null == mImageViewRef.get()){
return null;
}
mURL = params[0];
// Now we're not on the main thread we can check all caches
CacheableBitmapDrawable result = mCache.get(mURL, mDecodeOpts);
if(null == result){
Log.w("CACHE", "Downloading: " + mURL);
// The bitmap isn't cached so download from the web
HttpURLConnection conn = (HttpURLConnection)new URL(mURL).openConnection();
InputStream is = new BufferedInputStream(conn.getInputStream());
// Add to cache
result = mCache.put(mURL, is, mDecodeOpts);
}
else{
Log.w("CACHE", "Got from Disk Cache: " + mURL);
}
return result;
}
catch(IOException e){
Log.e("Error downloading image", e.toString());
}
catch(OutOfMemoryError e){
Log.e(TAG, "running out of memory, trimming image memory cache");
outOfMemoryFailure = true;
}
return null;
}
#Override
protected void onPostExecute(final CacheableBitmapDrawable result)
{
// super.onPostExecute(result);
if(outOfMemoryFailure || result == null || !result.hasValidBitmap()){
mCache.trimMemory();
// viewRef.get().loadImageAsync(mURL, mDecodeOpts);
Log.e(TAG, "image probably did not load::" + mURL);
}
else{
if(BuildConfig.DEBUG){
Log.d("bitmapCache", "NetworkedCacheableImageView.ImageUrlAsyncTask.onPostExecute() WIDTH:"
+ result.getBitmap().getWidth());
Log.d("bitmapCache", "NetworkedCacheableImageView.ImageUrlAsyncTask.onPostExecute() HEIGHT:"
+ result.getBitmap().getHeight());
}
Log.i(TAG, "RESULT for :" + mURL + " mImageViewRef::" + mImageViewRef + " outOfMemoryFailure::"
+ outOfMemoryFailure);
if(result != null){
Log.i(TAG, "RESULT object for :" + mURL + " result:hasValidBitmap" + result.hasValidBitmap()
+ " result:isReferencedByCache" + result.isReferencedByCache() + " result.isBeingDisplayed() "
+ result.isBeingDisplayed());
}
Runnable runnable = new Runnable()
{
#Override
public void run()
{
if(mImageViewRef != null){
final ImageView iv = mImageViewRef.get();
Log.e(TAG, "RESULT image view reference :" + mURL + " view ref::" + iv);
if(null != iv){
iv.setImageDrawable(result);
if(mLoadListener != null){
mLoadListener.onImageLoaded(true);
}
}
}
}
};
Handler handler = new Handler();
handler.postDelayed(runnable, 50);
}
super.onPostExecute(result);
}
}
private final BitmapLruCache mCache;
private ImageUrlAsyncTask mCurrentTask;
private ImageLoadListener mListener;
public NetworkedCacheableImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
mCache = WatchApplication.getBitmapCache();
}
public void setLoadListener(ImageLoadListener listener)
{
mListener = listener;
}
public void removeListener()
{
mListener = null;
}
/**
* Loads the Bitmap.
*
* #param url
* - URL of image
* #param fullSize
* - Whether the image should be kept at the original size
* #return true if the bitmap was found in the cache
*/
public boolean loadImage(String url, final boolean fullSize)
{
setImageDrawable(null);
// First check whether there's already a task running, if so cancel it
if(TextUtils.isEmpty(url))
return false;
if(null != mCurrentTask){
mCurrentTask.cancel(false);
}
// Check to see if the memory cache already has the bitmap. We can
// safely do
// this on the main thread.
BitmapDrawable wrapper = mCache.getFromMemoryCache(url);
if(null != wrapper){
// The cache has it, so just display it
if(BuildConfig.DEBUG){
Log.w(TAG, "CACHE. FOUND IN MEMORY:" + url);
}
setImageDrawable(wrapper);
if(mListener != null){
mListener.onImageLoaded(false);
}
return true;
}
else{
// Memory Cache doesn't have the URL, do threaded request...
BitmapFactory.Options decodeOpts = null;
if(!fullSize){
decodeOpts = new BitmapFactory.Options();
// decodeOpts.inDensity = DisplayMetrics.DENSITY_XHIGH;
decodeOpts.inPurgeable = true;
decodeOpts.outHeight = this.getHeight();
decodeOpts.outWidth = this.getWidth();
}
loadImageAsync(url, decodeOpts);
return false;
}
}
public void loadImageAsync(String url, BitmapFactory.Options decodeOpts)
{
mCurrentTask = new ImageUrlAsyncTask(this, mCache, decodeOpts, mListener, this);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
SDK11.executeOnThreadPool(mCurrentTask, url);
}
else{
mCurrentTask.execute(url);
}
}
}
Thanks in advance for any help!
Two things worth trying -
For chaining animation operations use a listener:
mPlaceHolder.animate()
.alpha(0f)
.scaleX(0.9f)
.scaleY(0.9f)
.rotationY(90)
.setDuration(DURATION)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mCacheableImage.setImageDrawable(drawable);
mCacheableImage.animate()
.alpha(1f)
.scaleY(1f)
.scaleX(1f)
.rotationY(0)
.setDuration(DURATION)
.setListener(null);
}
});
Use setHasTransientState() to ensure the views are not recycled in the ListView/GridView. See this DevByte video for more info.
enter code hereI want to do an advertisement program in android from openx server. But i am getting a bigger advertisement in limited area . I want a advertisement to fit an specific area in all android phones of all android phone dimensions.
I tried this code::
In the Xml , i gave ::
<LinearLayout
android:layout_alignParentBottom="true"
android:background="#color/black"
android:gravity="center_horizontal|center_vertical"
android:id="#+id/lLayout_ua_Ads"
android:layout_height="38dip"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_width="300dip"
android:orientation="vertical">
<xstream.android.loyalone.openxads.OpenxAdView
android:id="#+id/openAdView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
In the main program,i gave ::
class AdManager{
Context mContext;
LinearLayout mLinearLayoutAds;
Timer mReloadAdTimer;
OpenxAdView openAd;
public AdManager(Context context, LinearLayout linearLayoutAds){
this.mContext = context;
this.mLinearLayoutAds = linearLayoutAds;
mReloadAdTimer = new Timer();
openAd = (OpenxAdView)findViewById(R.id.openAdView);
openAd.setDeliveryURL("openx.marzar.net/www/delivery");
openAd.setZoneID(1);
}
private void startShowing(){
openAd.load();
mReloadAdTimer.schedule(timerTaskAdUpdate, 10000, 10000);
}
TimerTask timerTaskAdUpdate = new TimerTask() {
#Override
public void run() {
openAd.load();
}
};
protected void removeImage() {
// TODO Auto-generated method stub
this.mLinearLayoutAds.removeAllViews();
}
private void setAdWidjet(){
}
public void onUpdating() {
setAdWidjet();
}
protected void cleanUp() {
try{
mReloadAdTimer.cancel();
}catch (Exception e) {
}
}
}
For getting openx ad , i gave ::
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Random;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
public class OpenxAdView extends ViewGroup {
private static final String ATTRS_NS = "http://denivip.ru/schemas/android/openx/0.1";
private static final String LOGTAG = "OpenXAd";
private static final String PARAMETER_DELIVERY_URL = "delivery_url";
private static final String PARAMETER_JS_TAG_URL = "js_tag_url";
private static final String PARAMETER_ZONE_ID = "zone_id";
private static final String PARAMETER_HAS_HTTPS = "has_https";
private static final String PARAMETER_SOURCE = "source";
private static final String HTML_DOCUMENT_TEMPLATE = "<html><head><style>* {padding: 0; margin: 0; background-color: transparent;}</style></head>\n"
+ "<body>%s</pre></body></html>";
private static final String JS_TAG = ""
+ "<script type='text/javascript' src='%1$s?zoneid=%2$d&charset=UTF-8"
+ "&cb=%4$d&charset=UTF-8&source=%3$s'></script>";
private WebView webView;
private String deliveryURL;
private String jsTagURL = "ajs.php";
//private String jsTagURL = "avw.php";
private Integer zoneID;
private boolean hasHTTPS = false;
private String source;
private Random prng = new Random();
private Resources res;
/**
* Initialize widget.
*
* #param context
*/
public OpenxAdView(Context context) {
super(context);
this.res = context.getResources();
this.webView = new WebView(context);
initWebView();
}
/**
* Initialize widget. If delivery_url and zone_id attributes were set in
* layout file, ad will be loaded automatically.
*
* #param context
* #param attrs
* #param defStyle
*/
public OpenxAdView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.res = context.getResources();
initAttributes(attrs);
this.webView = new WebView(context, attrs, defStyle);
initWebView();
}
/**
* Initialize widget. If delivery_url and zone_id attributes were set in
* layout file, ad will be loaded automatically.
*
* #param context
* #param attrs
*/
public OpenxAdView(Context context, AttributeSet attrs) {
super(context, attrs);
this.res = context.getResources();
initAttributes(attrs);
this.webView = new WebView(context, attrs);
initWebView();
}
private void initAttributes(AttributeSet attrs) {
setDeliveryURL(attrs);
setJsTagURL(attrs);
setZoneID(attrs);
setHasHTTPS(attrs);
setSource(attrs);
}
private void initWebView() {
DisplayMetrics d=this.res.getDisplayMetrics();
int wndWidth= d.widthPixels;
int wndHeight= d.heightPixels;
if(wndHeight<=480)
webView.setInitialScale(42);
else
webView.setInitialScale(83);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setPluginsEnabled(true);
settings.setAllowFileAccess(false);
// settings.setPluginState(WebSettings.PluginState.ON);
webView.setBackgroundColor(0x00000000); // transparent
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);
webView.setWebChromeClient(new WebChromeClient());
addView(webView);
}
protected String getZoneTemplate(int zoneID) {
String raw;
try {
String zoneTag = String.format(JS_TAG,
(hasHTTPS ? "https://" : "http://") + deliveryURL + '/' + jsTagURL,
zoneID,
source == null ? "" : URLEncoder.encode(source, "utf-8"),
prng.nextLong());
raw = String.format(HTML_DOCUMENT_TEMPLATE, zoneTag);
return raw;
}
catch (UnsupportedEncodingException e) {
// Log.wtf(LOGTAG, "UTF-8 not supported?!", e);
}
return null;
}
#Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
webView.layout(left, top, right, bottom);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
load();
}
/**
* Load ad from OpenX server using the parameters that were set previously.
* This will not work if the following minimum required parameters were not
* set: delivery_url and zone_id.
*/
public void load() {
//webView.clearView();
if (zoneID != null) {
load(zoneID);
}
else {
Log.w(LOGTAG, "zoneID is empty");
}
}
/**
* Load ad from OpenX server using the parameters that were set previously
* and the supplied zoneID. This will not work if the required parameter
* delivery_url was not set.
*
* #see #load()
* #param zoneID ID of OpenX zone to load ads from.
*/
public void load(int zoneID) {
// check required parameters
if (deliveryURL != null) {
// webView.clearView();
webView.loadDataWithBaseURL(null, getZoneTemplate(zoneID), "text/html", "utf-8", null);
}
else {
Log.w(LOGTAG, "deliveryURL is empty");
}
}
public String getDeliveryURL() {
return deliveryURL;
}
/**
* The path to server and directory containing OpenX delivery scripts in the
* form servername/path. This parameter is required. Example:
* openx.example.com/delivery.
*
* #param deliveryURL
*/
public void setDeliveryURL(String deliveryURL) {
this.deliveryURL = deliveryURL;
}
private void setDeliveryURL(AttributeSet attrs) {
int delivery_url = attrs.getAttributeResourceValue(ATTRS_NS, PARAMETER_DELIVERY_URL, -1);
if (delivery_url != -1) {
this.deliveryURL = res.getString(delivery_url);
}
else {
this.deliveryURL = attrs.getAttributeValue(ATTRS_NS, PARAMETER_DELIVERY_URL);
}
}
public String getJsTagURL() {
return jsTagURL;
}
/**
* The name of OpenX script that serves ad code for simple JavaScript type
* tag. Default: ajs.php. This parameter usually does not need to be
* changed.
*
* #param jsTagURL
*/
public void setJsTagURL(String jsTagURL) {
this.jsTagURL = jsTagURL;
}
private void setJsTagURL(AttributeSet attrs) {
int js_tag_url_id = attrs.getAttributeResourceValue(ATTRS_NS, PARAMETER_JS_TAG_URL, -1);
if (js_tag_url_id != -1) {
this.jsTagURL = res.getString(js_tag_url_id);
}
else {
String js_tag_url = attrs.getAttributeValue(ATTRS_NS, PARAMETER_JS_TAG_URL);
if (js_tag_url != null) {
this.jsTagURL = js_tag_url;
}
}
}
public Integer getZoneID() {
return zoneID;
}
/**
* The ID of OpenX zone from which ads should be selected to display inside
* the widget. This parameter is required unless you use load(int) method.
*
* #param zoneID
*/
public void setZoneID(Integer zoneID) {
this.zoneID = zoneID;
}
private void setZoneID(AttributeSet attrs) {
int zone_id_rs = attrs.getAttributeResourceValue(ATTRS_NS, PARAMETER_ZONE_ID, -1);
if (zone_id_rs != -1) {
this.zoneID = new Integer(res.getInteger(zone_id_rs));
}
else {
int zone_id = attrs.getAttributeIntValue(ATTRS_NS, PARAMETER_ZONE_ID, -1);
if (zone_id != -1) {
this.zoneID = new Integer(zone_id);
}
}
}
public boolean hasHTTPS() {
return hasHTTPS;
}
/**
* Set this to true if ads should be served over HTTPS protocol. Default:
* false.
*
* #param hasHTTPS
*/
public void setHasHTTPS(boolean hasHTTPS) {
this.hasHTTPS = hasHTTPS;
}
private void setHasHTTPS(AttributeSet attrs) {
int has_https = attrs.getAttributeResourceValue(ATTRS_NS, PARAMETER_HAS_HTTPS, -1);
if (has_https != -1) {
this.hasHTTPS = res.getBoolean(has_https);
}
else {
this.hasHTTPS = attrs.getAttributeBooleanValue(ATTRS_NS, PARAMETER_HAS_HTTPS, false);
}
}
public String getSource() {
return source;
}
/**
* This parameter can be used to target ads by its value. It is optional.
*
* #param source
*/
public void setSource(String source) {
this.source = source;
}
private void setSource(AttributeSet attrs) {
int source_id = attrs.getAttributeResourceValue(ATTRS_NS, PARAMETER_SOURCE, -1);
if (source_id != -1) {
this.source = res.getString(source_id);
}
else {
this.source = attrs.getAttributeValue(ATTRS_NS, PARAMETER_SOURCE);
}
}
}
please give your solutions for this problem . Thanks in advance.