Related
Not so familiar with Android studio as I keep running into problems. My app was running fine until something broke in relation to the cloud backend, which I never touched and this error keeps me from continuing:
warning: [options] bootstrap class path not set in conjunction with -source 1.7
C:\Users\JC\Projects\ca.usimage.resto.RestonetActivity\backend\build\generated-source\endpoints\java\com\example\jean\myapplication\backend\myApi\MyApi.java:279: error: method does not override or implement a method from a supertype
#Override
^
C:\Users\JC\Projects\ca.usimage.resto.RestonetActivity\backend\build\generated-source\endpoints\java\com\example\jean\myapplication\backend\myApi\MyApi.java:281: error: cannot find symbol
return (Builder) super.setBatchPath(batchPath);
^
symbol: method setBatchPath(String)
2 errors
1 warning
I upgraded to Android Studio 3, updated everything I could, even backtracked to a new project from a year old github backup and I still get the error.
What went wrong?
About to reinstall Android Studio, or switch back to Eclipse (yuck)
/*
* 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.
*/
/*
* This code was generated by https://github.com/google/apis-client-generator/
* (build: 2017-11-07 19:12:12 UTC)
* on 2017-11-21 at 02:13:58 UTC
* Modify at your own risk.
*/
package com.example.jean.myapplication.backend.myApi;
/**
* Service definition for MyApi (v1).
*
* <p>
* This is an API
* </p>
*
* <p>
* For more information about this service, see the
* API Documentation
* </p>
*
* <p>
* This service uses {#link MyApiRequestInitializer} to initialize global parameters via its
* {#link Builder}.
* </p>
*
* #since 1.3
* #author Google, Inc.
*/
#SuppressWarnings("javadoc")
public class MyApi extends com.google.api.client.googleapis.services.json.AbstractGoogleJsonClient {
// Note: Leave this static initializer at the top of the file.
static {
com.google.api.client.util.Preconditions.checkState(
com.google.api.client.googleapis.GoogleUtils.MAJOR_VERSION == 1 &&
com.google.api.client.googleapis.GoogleUtils.MINOR_VERSION >= 15,
"You are currently running with version %s of google-api-client. " +
"You need at least version 1.15 of google-api-client to run version " +
"1.23.0 of the myApi library.", com.google.api.client.googleapis.GoogleUtils.VERSION);
}
/**
* The default encoded root URL of the service. This is determined when the library is generated
* and normally should not be changed.
*
* #since 1.7
*/
public static final String DEFAULT_ROOT_URL = "https://myApplicationId.appspot.com/_ah/api/";
/**
* The default encoded service path of the service. This is determined when the library is
* generated and normally should not be changed.
*
* #since 1.7
*/
public static final String DEFAULT_SERVICE_PATH = "myApi/v1/sayHi/";
/**
* The default encoded batch path of the service. This is determined when the library is
* generated and normally should not be changed.
*
* #since 1.23
*/
public static final String DEFAULT_BATCH_PATH = "batch";
/**
* The default encoded base URL of the service. This is determined when the library is generated
* and normally should not be changed.
*/
public static final String DEFAULT_BASE_URL = DEFAULT_ROOT_URL + DEFAULT_SERVICE_PATH;
/**
* Constructor.
*
* <p>
* Use {#link Builder} if you need to specify any of the optional parameters.
* </p>
*
* #param transport HTTP transport, which should normally be:
* <ul>
* <li>Google App Engine:
* {#code com.google.api.client.extensions.appengine.http.UrlFetchTransport}</li>
* <li>Android: {#code newCompatibleTransport} from
* {#code com.google.api.client.extensions.android.http.AndroidHttp}</li>
* <li>Java: {#link com.google.api.client.googleapis.javanet.GoogleNetHttpTransport#newTrustedTransport()}
* </li>
* </ul>
* #param jsonFactory JSON factory, which may be:
* <ul>
* <li>Jackson: {#code com.google.api.client.json.jackson2.JacksonFactory}</li>
* <li>Google GSON: {#code com.google.api.client.json.gson.GsonFactory}</li>
* <li>Android Honeycomb or higher:
* {#code com.google.api.client.extensions.android.json.AndroidJsonFactory}</li>
* </ul>
* #param httpRequestInitializer HTTP request initializer or {#code null} for none
* #since 1.7
*/
public MyApi(com.google.api.client.http.HttpTransport transport, com.google.api.client.json.JsonFactory jsonFactory,
com.google.api.client.http.HttpRequestInitializer httpRequestInitializer) {
this(new Builder(transport, jsonFactory, httpRequestInitializer));
}
/**
* #param builder builder
*/
MyApi(Builder builder) {
super(builder);
}
#Override
protected void initialize(com.google.api.client.googleapis.services.AbstractGoogleClientRequest<?> httpClientRequest) throws java.io.IOException {
super.initialize(httpClientRequest);
}
/**
* Create a request for the method "sayHi".
*
* This request holds the parameters needed by the myApi server. After setting any optional
* parameters, call the {#link SayHi#execute()} method to invoke the remote operation.
*
* #param name
* #return the request
*/
public SayHi sayHi(java.lang.String name) throws java.io.IOException {
SayHi result = new SayHi(name);
initialize(result);
return result;
}
public class SayHi extends MyApiRequest<com.example.jean.myapplication.backend.myApi.model.MyBean> {
private static final String REST_PATH = "{name}";
/**
* Create a request for the method "sayHi".
*
* This request holds the parameters needed by the the myApi server. After setting any optional
* parameters, call the {#link SayHi#execute()} method to invoke the remote operation. <p> {#link
* SayHi#initialize(com.google.api.client.googleapis.services.AbstractGoogleClientRequest)} must
* be called to initialize this instance immediately after invoking the constructor. </p>
*
* #param name
* #since 1.13
*/
protected SayHi(java.lang.String name) {
super(MyApi.this, "POST", REST_PATH, null, com.example.jean.myapplication.backend.myApi.model.MyBean.class);
this.name = com.google.api.client.util.Preconditions.checkNotNull(name, "Required parameter name must be specified.");
}
#Override
public SayHi setAlt(java.lang.String alt) {
return (SayHi) super.setAlt(alt);
}
#Override
public SayHi setFields(java.lang.String fields) {
return (SayHi) super.setFields(fields);
}
#Override
public SayHi setKey(java.lang.String key) {
return (SayHi) super.setKey(key);
}
#Override
public SayHi setOauthToken(java.lang.String oauthToken) {
return (SayHi) super.setOauthToken(oauthToken);
}
#Override
public SayHi setPrettyPrint(java.lang.Boolean prettyPrint) {
return (SayHi) super.setPrettyPrint(prettyPrint);
}
#Override
public SayHi setQuotaUser(java.lang.String quotaUser) {
return (SayHi) super.setQuotaUser(quotaUser);
}
#Override
public SayHi setUserIp(java.lang.String userIp) {
return (SayHi) super.setUserIp(userIp);
}
#com.google.api.client.util.Key
private java.lang.String name;
/**
*/
public java.lang.String getName() {
return name;
}
public SayHi setName(java.lang.String name) {
this.name = name;
return this;
}
#Override
public SayHi set(String parameterName, Object value) {
return (SayHi) super.set(parameterName, value);
}
}
/**
* Builder for {#link MyApi}.
*
* <p>
* Implementation is not thread-safe.
* </p>
*
* #since 1.3.0
*/
public static final class Builder extends com.google.api.client.googleapis.services.json.AbstractGoogleJsonClient.Builder {
/**
* Returns an instance of a new builder.
*
* #param transport HTTP transport, which should normally be:
* <ul>
* <li>Google App Engine:
* {#code com.google.api.client.extensions.appengine.http.UrlFetchTransport}</li>
* <li>Android: {#code newCompatibleTransport} from
* {#code com.google.api.client.extensions.android.http.AndroidHttp}</li>
* <li>Java: {#link com.google.api.client.googleapis.javanet.GoogleNetHttpTransport#newTrustedTransport()}
* </li>
* </ul>
* #param jsonFactory JSON factory, which may be:
* <ul>
* <li>Jackson: {#code com.google.api.client.json.jackson2.JacksonFactory}</li>
* <li>Google GSON: {#code com.google.api.client.json.gson.GsonFactory}</li>
* <li>Android Honeycomb or higher:
* {#code com.google.api.client.extensions.android.json.AndroidJsonFactory}</li>
* </ul>
* #param httpRequestInitializer HTTP request initializer or {#code null} for none
* #since 1.7
*/
public Builder(com.google.api.client.http.HttpTransport transport, com.google.api.client.json.JsonFactory jsonFactory,
com.google.api.client.http.HttpRequestInitializer httpRequestInitializer) {
super(
transport,
jsonFactory,
DEFAULT_ROOT_URL,
DEFAULT_SERVICE_PATH,
httpRequestInitializer,
false);
setBatchPath(DEFAULT_BATCH_PATH);
}
/** Builds a new instance of {#link MyApi}. */
#Override
public MyApi build() {
return new MyApi(this);
}
#Override
public Builder setRootUrl(String rootUrl) {
return (Builder) super.setRootUrl(rootUrl);
}
#Override
public Builder setServicePath(String servicePath) {
return (Builder) super.setServicePath(servicePath);
}
#Override
public Builder setBatchPath(String batchPath) {
return (Builder) super.setBatchPath(batchPath);
}
#Override
public Builder setHttpRequestInitializer(com.google.api.client.http.HttpRequestInitializer httpRequestInitializer) {
return (Builder) super.setHttpRequestInitializer(httpRequestInitializer);
}
#Override
public Builder setApplicationName(String applicationName) {
return (Builder) super.setApplicationName(applicationName);
}
#Override
public Builder setSuppressPatternChecks(boolean suppressPatternChecks) {
return (Builder) super.setSuppressPatternChecks(suppressPatternChecks);
}
#Override
public Builder setSuppressRequiredParameterChecks(boolean suppressRequiredParameterChecks) {
return (Builder) super.setSuppressRequiredParameterChecks(suppressRequiredParameterChecks);
}
#Override
public Builder setSuppressAllChecks(boolean suppressAllChecks) {
return (Builder) super.setSuppressAllChecks(suppressAllChecks);
}
/**
* Set the {#link MyApiRequestInitializer}.
*
* #since 1.12
*/
public Builder setMyApiRequestInitializer(
MyApiRequestInitializer myapiRequestInitializer) {
return (Builder) super.setGoogleClientRequestInitializer(myapiRequestInitializer);
}
#Override
public Builder setGoogleClientRequestInitializer(
com.google.api.client.googleapis.services.GoogleClientRequestInitializer googleClientRequestInitializer) {
return (Builder) super.setGoogleClientRequestInitializer(googleClientRequestInitializer);
}
}
}
Can someone provide an example of how to use the new AlwaysOnHotwordDetector class in Android?
I'd like to build an app, that when the app is running in the background, can detect a hotword like "next", or "back", or "pause".
Unless I have a huge blind spot, I don't think third-party applications can make use of this API. Its strange that AlwaysOnHotwordDetector (and related classes VoiceInteractionService etc.) have been granted public access.
If you are building a privileged app, look through these test projects from AOSP:
Voice Interaction - Basic AlwaysOnHotwordDetector usage/implementation
http://androidxref.com/5.0.0_r2/xref/frameworks/base/tests/VoiceInteraction/
Voice Enrollment - http://androidxref.com/5.0.0_r2/xref/frameworks/base/tests/VoiceEnrollment/
While trying to make this work, I came upon this:
AlwaysOnHotwordDetector's constructor:
/**
* #param text The keyphrase text to get the detector for.
* #param locale The java locale for the detector.
* #param callback A non-null Callback for receiving the recognition events.
* #param voiceInteractionService The current voice interaction service.
* #param modelManagementService A service that allows management of sound models.
*
* #hide
*/
public AlwaysOnHotwordDetector(String text, Locale locale, Callback callback,
KeyphraseEnrollmentInfo keyphraseEnrollmentInfo,
IVoiceInteractionService voiceInteractionService,
IVoiceInteractionManagerService modelManagementService) {
mText = text;
mLocale = locale;
mKeyphraseEnrollmentInfo = keyphraseEnrollmentInfo;
mKeyphraseMetadata = mKeyphraseEnrollmentInfo.getKeyphraseMetadata(text, locale);
mExternalCallback = callback;
mHandler = new MyHandler();
mInternalCallback = new SoundTriggerListener(mHandler);
mVoiceInteractionService = voiceInteractionService;
mModelManagementService = modelManagementService;
new RefreshAvailabiltyTask().execute();
}
The statement of interest here is:
mKeyphraseMetadata = mKeyphraseEnrollmentInfo.getKeyphraseMetadata(text, locale);
What does KeyphraseEnrollmentInfo#getKeyphraseMetadata(String, Locale) do?
/**
* Gets the {#link KeyphraseMetadata} for the given keyphrase and locale, null if any metadata
* isn't available for the given combination.
*
* #param keyphrase The keyphrase that the user needs to be enrolled to.
* #param locale The locale for which the enrollment needs to be performed.
* This is a Java locale, for example "en_US".
* #return The metadata, if the enrollment client supports the given keyphrase
* and locale, null otherwise.
*/
public KeyphraseMetadata getKeyphraseMetadata(String keyphrase, Locale locale) {
if (mKeyphrases == null || mKeyphrases.length == 0) {
Slog.w(TAG, "Enrollment application doesn't support keyphrases");
return null;
}
for (KeyphraseMetadata keyphraseMetadata : mKeyphrases) {
// Check if the given keyphrase is supported in the locale provided by
// the enrollment application.
if (keyphraseMetadata.supportsPhrase(keyphrase)
&& keyphraseMetadata.supportsLocale(locale)) {
return keyphraseMetadata;
}
}
Slog.w(TAG, "Enrollment application doesn't support the given keyphrase/locale");
return null;
}
At this point, my example project kept telling me: Enrollment application doesn't support keyphrases. So, digging a bit further - to support keyphrases, we need to provide additional meta-data:
// Taken from class KeyphraseEnrollmentInfo
/**
* Name under which a Hotword enrollment component publishes information about itself.
* This meta-data should reference an XML resource containing a
* <code><{#link
* android.R.styleable#VoiceEnrollmentApplication
* voice-enrollment-application}></code> tag.
*/
private static final String VOICE_KEYPHRASE_META_DATA = "android.voice_enrollment";
Additionally, we will need the android.permission.MANAGE_VOICE_KEYPHRASES permission. This is where the example project gets stuck:
<!-- Must be required by hotword enrollment application,
to ensure that only the system can interact with it.
#hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.MANAGE_VOICE_KEYPHRASES"
android:label="#string/permlab_manageVoiceKeyphrases"
android:description="#string/permdesc_manageVoiceKeyphrases"
android:protectionLevel="signature|system" />
The permission required to support hotword detection is not available to third-party applications. I still can't figure out why package android.service.voice package has public access. Perhaps I am missing something here.
I got several UIDs like this:
10022, 10011, 1000
Actually I know the user names of them are u0_a22, u0_a11, system.
But the question is, how can I get the user name using UIDs? There is no /etc/passwd file at all.
I wrote a utility class to get the UID/GID name by hardcoding values from android_filesystem_config.h.
Usage:
String uid = AndroidFilesystemConfig.getNameForId(1000);
AndroidFilesystemConfig.java
import android.os.Build;
import android.util.SparseArray;
import java.util.Locale;
/**
* <p>System Users and Groups for the Android platform as specified in
* android_filesystem_config.h.</p>
*
* <p>Last updated: April 20th, 2016</p>
*
* <p><b>Note:</b> Some OEMs may have specific UIDs for other system users not in this class.</p>
*/
public class AndroidFilesystemConfig {
/* first app user */
private static final int AID_APP = 10000;
/* offset for uid ranges for each user */
private static final int AID_USER = 100000;
/* start of gids for apps in each user to share */
private static final int AID_SHARED_GID_START = 50000;
/* end of gids for apps in each user to share */
private static final int AID_SHARED_GID_END = 59999;
private static final SparseArray<String> SYSTEM_IDS = new SparseArray<>();
static {
putSystemId(0, "root"); /* traditional unix root user */
putSystemId(1000, "system"); /* system server */
putSystemId(1001, "radio"); /* telephony subsystem, RIL */
putSystemId(1002, "bluetooth"); /* bluetooth subsystem */
putSystemId(1003, "graphics"); /* graphics devices */
putSystemId(1004, "input"); /* input devices */
putSystemId(1005, "audio"); /* audio devices */
putSystemId(1006, "camera"); /* camera devices */
putSystemId(1007, "log"); /* log devices */
putSystemId(1008, "compass"); /* compass device */
putSystemId(1009, "mount"); /* mountd socket */
putSystemId(1010, "wifi"); /* wifi subsystem */
putSystemId(1011, "adb"); /* android debug bridge (adbd) */
putSystemId(1012, "install"); /* group for installing packages */
putSystemId(1013, "media"); /* mediaserver process */
putSystemId(1014, "dhcp"); /* dhcp client */
putSystemId(1015, "sdcard_rw"); /* external storage write access */
putSystemId(1016, "vpn"); /* vpn system */
putSystemId(1017, "keystore"); /* keystore subsystem */
putSystemId(1018, "usb"); /* USB devices */
putSystemId(1019, "drm"); /* DRM server */
putSystemId(1020, "mdnsr"); /* MulticastDNSResponder (service discovery) */
putSystemId(1021, "gps"); /* GPS daemon */
// 1022 is deprecated and not used.
putSystemId(1023, "media_rw"); /* internal media storage write access */
putSystemId(1024, "mtp"); /* MTP USB driver access */
// 1025 is deprecated and not used.
putSystemId(1026, "drmrpc"); /* group for drm rpc */
putSystemId(1027, "nfc"); /* nfc subsystem */
putSystemId(1028, "sdcard_r"); /* external storage read access */
putSystemId(1029, "clat"); /* clat part of nat464 */
putSystemId(1030, "loop_radio"); /* loop radio devices */
putSystemId(1031, "mediadrm"); /* MediaDrm plugins */
putSystemId(1032, "package_info"); /* access to installed package details */
putSystemId(1033, "sdcard_pics"); /* external storage photos access */
putSystemId(1034, "sdcard_av"); /* external storage audio/video access */
putSystemId(1035, "sdcard_all"); /* access all users external storage */
putSystemId(1036, "logd"); /* log daemon */
putSystemId(1037, "shared_relro"); /* creator of shared GNU RELRO files */
putSystemId(1038, "dbus"); /* dbus-daemon IPC broker process */
putSystemId(1039, "tlsdate"); /* tlsdate unprivileged user */
putSystemId(1040, "mediaex"); /* mediaextractor process */
putSystemId(1041, "audioserver"); /* audioserver process */
putSystemId(1042, "metrics_coll"); /* metrics_collector process */
putSystemId(1043, "metricsd"); /* metricsd process */
putSystemId(1044, "webserv"); /* webservd process */
putSystemId(1045, "debuggerd"); /* debuggerd unprivileged user */
putSystemId(1046, "mediacodec"); /* mediacodec process */
putSystemId(1047, "cameraserver"); /* cameraserver process */
putSystemId(1048, "firewall"); /* firewalld process */
putSystemId(1049, "trunks"); /* trunksd process (TPM daemon) */
putSystemId(1050, "nvram"); /* Access-controlled NVRAM */
putSystemId(1051, "dns"); /* DNS resolution daemon (system: netd) */
putSystemId(1052, "dns_tether"); /* DNS resolution daemon (tether: dnsmasq) */
putSystemId(1053, "webview_zygote"); /* WebView zygote process */
putSystemId(1054, "vehicle_network"); /* Vehicle network service */
putSystemId(1055, "media_audio"); /* GID for audio files on internal media storage */
putSystemId(1056, "media_video"); /* GID for video files on internal media storage */
putSystemId(1057, "media_image"); /* GID for image files on internal media storage */
putSystemId(2000, "shell"); /* adb and debug shell user */
putSystemId(2001, "cache"); /* cache access */
putSystemId(2002, "diag"); /* access to diagnostic resources */
/* The range 2900-2999 is reserved for OEMs */
// The 3000 series are intended for use as supplemental group id's only. They indicate
// special Android capabilities that the kernel is aware of.
putSystemId(3001, "net_bt_admin"); /* bluetooth: get any socket */
putSystemId(3002, "net_bt"); /* bluetooth: get sco, rfcomm or l2cap sockets */
putSystemId(3003, "inet"); /* can get AF_INET and AF_INET6 sockets */
putSystemId(3004, "net_raw"); /* can get raw INET sockets */
putSystemId(3005, "net_admin"); /* can configure interfaces and routing tables. */
putSystemId(3006, "net_bw_stats"); /* read bandwidth statistics */
putSystemId(3007, "net_bw_acct"); /* change bandwidth statistics accounting */
putSystemId(3008, "net_bt_stack"); /* bluetooth: access config files */
putSystemId(3009, "readproc"); /* Allow /proc read access */
putSystemId(3010, "wakelock"); /* Allow system wakelock read/write access */
/* The range 5000-5999 is also reserved for OEMs. */
putSystemId(9997, "everybody"); /* shared between all apps in the same profile */
putSystemId(9998, "misc"); /* access to misc storage */
putSystemId(9999, "nobody");
}
private static void putSystemId(int id, String name) {
// Check if the uid exists before adding it so we don't add unsupported ids.
if (android.os.Process.getUidForName(name) != id) {
// Not valid on this system. Most likely due to a lower API.
return;
}
SYSTEM_IDS.put(id, name);
}
/**
* #return An array of system UIDs
*/
public static SparseArray<String> getSystemIds() {
return SYSTEM_IDS;
}
/**
* Returns the UID/GID name assigned to a particular id, or {#code null} if there is none.
*
* #param id
* The UID/GID of a process or file
* #return the name of the UID/GID or {#code null} if the id is unrecognized.
*/
public static String getNameForId(int id) {
String name = SYSTEM_IDS.get(id);
if (name == null) {
if (id >= AID_SHARED_GID_START && id <= AID_SHARED_GID_END) {
name = String.format(Locale.ENGLISH, "all_a%d", id - AID_SHARED_GID_START);
} else {
int appId = id - AID_APP;
int userId = 0;
// loop until we get the correct user id.
// 100000 is the offset for each user.
while (appId > AID_USER) {
appId -= AID_USER;
userId++;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
// u{user_id}_a{app_id} is used on API 17+ for multiple user account support.
name = String.format(Locale.ENGLISH, "u%d_a%d", userId, appId);
} else {
// app_{app_id} is used below API 17.
name = String.format(Locale.ENGLISH, "app_%d", appId);
}
}
}
return name;
}
private AndroidFilesystemConfig() {
throw new AssertionError("no instances");
}
}
Using Reflection:
Inspired by odexide's answer, here is some really ugly reflection I wouldn't advise using that will get the UID/GID name from getpwuid(uid_t):
public static String getNameForUid(int id) {
try {
Class<?> clazz = Class.forName("libcore.io.Libcore");
Field field = clazz.getDeclaredField("os");
if (!field.isAccessible()) {
field.setAccessible(true);
}
Object os = field.get(null);
if (os != null) {
Method getpwuid = os.getClass().getMethod("getpwuid", int.class);
if (getpwuid != null) {
if (!getpwuid.isAccessible()) {
getpwuid.setAccessible(true);
}
Object passwd = getpwuid.invoke(os, id);
if (passwd != null) {
Field pw_name = passwd.getClass().getDeclaredField("pw_name");
if (!pw_name.isAccessible()) {
pw_name.setAccessible(true);
}
return (String) pw_name.get(passwd);
}
}
}
} catch (Exception ignored) {
}
return null;
}
The UIDs are hardcoded for the android implemention of libc (bionic) and also are provided in ranges for apps. android_filesystem_config.h explains the mapping.
You should be able to use the bionic stubs (c++) for getpwuid(uid_t).
For more info on the stubs, see this AOSP documentation.
I'm trying to use MillenialMedia on my Phonegap app, but i just can't make it work.
I get the following errors on the LogCat:
08-12 12:52:36.755: I/MillennialMediaSDK(333): Initializing MMLayout.
08-12 12:52:37.385: W/MillennialMediaSDK(333): MMLayout adding view (MMWebView originally from(1) MRaidState(loading).) to AdType[(b) InternalId(1) LinkedId(0) isFinishing(false)]
08-12 12:52:37.645: W/MillennialMediaSDK(333): AdView onLayout changedtrue int left 0 int top 687 int right 480 int bottom 762
08-12 12:52:37.685: W/MillennialMediaSDK(333): Id check for parent: 1 versus 1
08-12 12:52:38.355: I/MillennialMediaSDK(333): Millennial ad return failed. Zero content length returned.
08-12 12:52:38.965: E/MillennialMediaSDK(333): Could not get a handshake. Not trusted server certificate
Here's my code:
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.logicstudio.paradise.Replay;
import android.os.Bundle;
import org.apache.cordova.*;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
public class Replay extends DroidGap
{
//Constants for tablet sized ads (728x90)
private static final int IAB_LEADERBOARD_WIDTH = 728;
private static final int IAB_LEADERBOARD_HEIGHT = 90;
private static final int MED_BANNER_WIDTH = 480;
private static final int MED_BANNER_HEIGHT = 60;
//Constants for phone sized ads (320x50)
private static final int BANNER_AD_WIDTH = 320;
private static final int BANNER_AD_HEIGHT = 50;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setIntegerProperty("splashscreen", R.drawable.splash);
super.loadUrl(Config.getStartUrl());
int placementWidth = BANNER_AD_WIDTH;
int placementHeight = BANNER_AD_HEIGHT;
//Finds an ad that best fits a users device.
if(canFit(IAB_LEADERBOARD_WIDTH)) {
placementWidth = IAB_LEADERBOARD_WIDTH;
placementHeight = IAB_LEADERBOARD_HEIGHT;
}
else if(canFit(MED_BANNER_WIDTH)) {
placementWidth = MED_BANNER_WIDTH;
placementHeight = MED_BANNER_HEIGHT;
}
com.millennialmedia.android.MMSDK.initialize(this);
com.millennialmedia.android.MMAdView adView = new com.millennialmedia.android.MMAdView(this);
LinearLayout layout = super.root;
adView.setApid("131468");
//Set your metadata in the MMRequest object
com.millennialmedia.android.MMRequest request = new com.millennialmedia.android.MMRequest();
//Add the MMRequest object to your MMAdView.
adView.setMMRequest(request);
//Sets the id to preserve your ad on configuration changes.
adView.setId(com.millennialmedia.android.MMSDK.getDefaultAdId());
//Set the ad size. Replace the width and height values if needed.
adView.setWidth(placementWidth);
adView.setHeight(placementHeight);
//Calculate the size of the adView based on the ad size. Replace the width and height values if needed.
int layoutWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, placementWidth, getResources().getDisplayMetrics());
int layoutHeight = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, placementHeight, getResources().getDisplayMetrics());
//Create the layout parameters using the calculated adView width and height.
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(layoutWidth, layoutHeight);
//This positions the banner.
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
adView.setLayoutParams(layoutParams);
//Add the adView to the layout. The layout is assumed to be a RelativeLayout.
layout.addView(adView);
adView.getAd();
}
protected boolean canFit(int adWidth) {
int adWidthPx = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, adWidth, getResources().getDisplayMetrics());
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
return metrics.widthPixels >= adWidthPx;
}
}
Any help will be greatly appreciated.
Thanks in advance!
PhoneGap works by throwing HTML/CSS/JS into a special WebView (CordovaWebView), which is running on the entire screen. The code that controls this default behavior lives inside their DroidApp class.
To get Millennial ads to work (or any standard Android controls, for that matter), you have to create a class that extends android.app.Activity (rather than DroidApp) and embed your CordovaWebView within that activity. That CordovaWebView will handle all of your app's Phonegap-related assets while your activity and its corresponding layout can handle your Android-specific classes (like Millennial's MMAdView).
To get a deeper understanding of how PhoneGap works on Android, I strongly recommend reading their docs here: http://cordova.apache.org/docs/en/2.7.0/guide_cordova-webview_android.md.html
To get more on how to specifically get Millennial's SDK working in that environment, talk to the support folks here: https://tools.mmedia.com/user/supportDevPortal
I want to create a object for IntentIntegrator in Android.
IntentIntegrator integrator = new IntentIntegrator(ZBarReaderActivity.this);
Here ZBarReaderActivity is my Activity class.
Thanks in Advance,
Please help me.
IntentIntegrator is class from com.google.zxing.integration.android.IntentIntegrator package.
which is used for identify Qr Code content is Telephone Number, WebSite, WebUrl.
IntentIntegrator integrator = new IntentIntegrator(this); /* "this" is enough */
for further information, watch this: http://www.youtube.com/watch?v=mVkaua4Lcvo
it's explained in german, but you can see the code and how they create a object for IntentIntegrator.
p.s: and you have to explain it in greater detail otherwise you cannot get an answer for your question.
This is the intentintegrator I've used
IntentIntegrator.java
/*
* Copyright 2009 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.your.package.name;
import com.your.package.name.IntentIntegrator;
import com.your.package.name.IntentResult;
import android.app.AlertDialog;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
/**
* <p>A utility class which helps ease integration with Barcode Scanner via {#link Intent}s. This is a simple
* way to invoke barcode scanning and receive the result, without any need to integrate, modify, or learn the
* project's source code.</p>
*
* <h2>Initiating a barcode scan</h2>
*
* <p>Integration is essentially as easy as calling {#link #initiateScan(Activity)} and waiting
* for the result in your app.</p>
*
* <p>It does require that the Barcode Scanner application is installed. The
* {#link #initiateScan(Activity)} method will prompt the user to download the application, if needed.</p>
*
* <p>There are a few steps to using this integration. First, your {#link Activity} must implement
* the method {#link Activity#onActivityResult(int, int, Intent)} and include a line of code like this:</p>
*
* <p>{#code
* public void onActivityResult(int requestCode, int resultCode, Intent intent) {
* IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
* if (scanResult != null) {
* // handle scan result
* }
* // else continue with any other code you need in the method
* ...
* }
* }</p>
*
* <p>This is where you will handle a scan result.
* Second, just call this in response to a user action somewhere to begin the scan process:</p>
*
* <p>{#code IntentIntegrator.initiateScan(yourActivity);}</p>
*
* <p>You can use {#link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence)} or
* {#link #initiateScan(Activity, int, int, int, int)} to customize the download prompt with
* different text labels.</p>
*
* <p>Note that {#link #initiateScan(Activity)} returns an {#link AlertDialog} which is non-null if the
* user was prompted to download the application. This lets the calling app potentially manage the dialog.
* In particular, ideally, the app dismisses the dialog if it's still active in its {#link Activity#onPause()}
* method.</p>
*
* <h2>Sharing text via barcode</h2>
*
* <p>To share text, encoded as a QR Code on-screen, similarly, see {#link #shareText(Activity, CharSequence)}.</p>
*
* <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
*
* #author Sean Owen
* #author Fred Lin
* #author Isaac Potoczny-Jones
* #author Brad Drehmer
*/
public final class IntentIntegrator {
public static final int REQUEST_CODE = 0x0ba7c0de; // get it?
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";
// supported barcode formats
public static final String PRODUCT_CODE_TYPES = "UPC_A,UPC_E,EAN_8,EAN_13";
public static final String ONE_D_CODE_TYPES = PRODUCT_CODE_TYPES + ",CODE_39,CODE_93,CODE_128";
public static final String QR_CODE_TYPES = "QR_CODE";
public static final String ALL_CODE_TYPES = null;
private IntentIntegrator() {
}
/**
* See {#link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence)} --
* same, but uses default English labels.
*/
public static AlertDialog initiateScan(Activity activity) {
return initiateScan(activity, DEFAULT_TITLE, DEFAULT_MESSAGE, DEFAULT_YES, DEFAULT_NO);
}
/**
* See {#link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence)} --
* same, but takes string IDs which refer
* to the {#link Activity}'s resource bundle entries.
*/
public static AlertDialog initiateScan(Activity activity,
int stringTitle,
int stringMessage,
int stringButtonYes,
int stringButtonNo) {
return initiateScan(activity,
activity.getString(stringTitle),
activity.getString(stringMessage),
activity.getString(stringButtonYes),
activity.getString(stringButtonNo));
}
/**
* See {#link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence)} --
* same, but scans for all supported barcode types.
* #param stringTitle title of dialog prompting user to download Barcode Scanner
* #param stringMessage text of dialog prompting user to download Barcode Scanner
* #param stringButtonYes text of button user clicks when agreeing to download
* Barcode Scanner (e.g. "Yes")
* #param stringButtonNo text of button user clicks when declining to download
* Barcode Scanner (e.g. "No")
* #return an {#link AlertDialog} if the user was prompted to download the app,
* null otherwise
*/
public static AlertDialog initiateScan(Activity activity,
CharSequence stringTitle,
CharSequence stringMessage,
CharSequence stringButtonYes,
CharSequence stringButtonNo) {
return initiateScan(activity,
stringTitle,
stringMessage,
stringButtonYes,
stringButtonNo,
ALL_CODE_TYPES);
}
/**
* Invokes scanning.
*
* #param stringTitle title of dialog prompting user to download Barcode Scanner
* #param stringMessage text of dialog prompting user to download Barcode Scanner
* #param stringButtonYes text of button user clicks when agreeing to download
* Barcode Scanner (e.g. "Yes")
* #param stringButtonNo text of button user clicks when declining to download
* Barcode Scanner (e.g. "No")
* #param stringDesiredBarcodeFormats a comma separated list of codes you would
* like to scan for.
* #return an {#link AlertDialog} if the user was prompted to download the app,
* null otherwise
* #throws InterruptedException if timeout expires before a scan completes
*/
public static AlertDialog initiateScan(Activity activity,
CharSequence stringTitle,
CharSequence stringMessage,
CharSequence stringButtonYes,
CharSequence stringButtonNo,
CharSequence stringDesiredBarcodeFormats) {
Intent intentScan = new Intent("com.google.zxing.client.android.SCAN");
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
// check which types of codes to scan for
if (stringDesiredBarcodeFormats != null) {
// set the desired barcode types
intentScan.putExtra("SCAN_FORMATS", stringDesiredBarcodeFormats);
}
try {
activity.startActivityForResult(intentScan, REQUEST_CODE);
return null;
} catch (ActivityNotFoundException e) {
return showDownloadDialog(activity, stringTitle, stringMessage, stringButtonYes, stringButtonNo);
}
}
private static AlertDialog showDownloadDialog(final Activity activity,
CharSequence stringTitle,
CharSequence stringMessage,
CharSequence stringButtonYes,
CharSequence stringButtonNo) {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
downloadDialog.setTitle(stringTitle);
downloadDialog.setMessage(stringMessage);
downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
Uri uri = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
activity.startActivity(intent);
}
});
downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
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 {#link IntentIntegrator}, 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");
return new IntentResult(contents, formatName);
} else {
return new IntentResult(null, null);
}
}
return null;
}
/**
* See {#link #shareText(Activity, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence)} --
* same, but uses default English labels.
*/
public static void shareText(Activity activity, CharSequence text) {
shareText(activity, text, DEFAULT_TITLE, DEFAULT_MESSAGE, DEFAULT_YES, DEFAULT_NO);
}
/**
* See {#link #shareText(Activity, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence)} --
* same, but takes string IDs which refer to the {#link Activity}'s resource bundle entries.
*/
public static void shareText(Activity activity,
CharSequence text,
int stringTitle,
int stringMessage,
int stringButtonYes,
int stringButtonNo) {
shareText(activity,
text,
activity.getString(stringTitle),
activity.getString(stringMessage),
activity.getString(stringButtonYes),
activity.getString(stringButtonNo));
}
/**
* 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 stringTitle title of dialog prompting user to download Barcode Scanner
* #param stringMessage text of dialog prompting user to download Barcode Scanner
* #param stringButtonYes text of button user clicks when agreeing to download
* Barcode Scanner (e.g. "Yes")
* #param stringButtonNo text of button user clicks when declining to download
* Barcode Scanner (e.g. "No")
*/
public static void shareText(Activity activity,
CharSequence text,
CharSequence stringTitle,
CharSequence stringMessage,
CharSequence stringButtonYes,
CharSequence stringButtonNo) {
Intent intent = new Intent();
intent.setAction("com.google.zxing.client.android.ENCODE");
intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
intent.putExtra("ENCODE_DATA", text);
try {
activity.startActivity(intent);
} catch (ActivityNotFoundException e) {
showDownloadDialog(activity, stringTitle, stringMessage, stringButtonYes, stringButtonNo);
}
}
}
IntentResult.java
/*
* Copyright 2009 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.your.package.name;
import com.your.package.name.IntentIntegrator;
/**
* <p>Encapsulates the result of a barcode scan invoked through {#link IntentIntegrator}.</p>
*
* #author Sean Owen
*/
public final class IntentResult {
private final String contents;
private final String formatName;
IntentResult(String contents, String formatName) {
this.contents = contents;
this.formatName = formatName;
}
/**
* #return raw content of barcode
*/
public String getContents() {
return contents;
}
/**
* #return name of format, like "QR_CODE", "UPC_A". See <code>BarcodeFormat</code> for more format names.
*/
public String getFormatName() {
return formatName;
}
}
And then to use it
private void someFunction()
{
IntentIntegrator.initiateScan(this);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case IntentIntegrator.REQUEST_CODE:
{
if (resultCode == RESULT_CANCELED){
}
else
{
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
String UPCScanned = scanResult.getContents();
}
break;
}
}
}
Add this in your dependencies
implementation 'com.journeyapps:zxing-android-embedded:4.1.0'