I’m trying to get AdMob ID’s into my app from JsonData so that I can change it in the future.
My Vision:
JSON
file will be uploaded into my server and a link of it will be inside the app. The AdMob ID found inside the json file should be used inside the app adUnitID. So far, I have made this:
String jsonToProcess = "https://drive.google.com/uc?id=113RUepiYecy5pBwj-t4BtBXwlQwgf-dU";
String interstialAd = new JsonParser().parse(jsonToProcess).getAsJsonObject()
.get("response").getAsJsonObject()
.get("Interstial AD").getAsString();
mInterstitialAd = new InterstitialAd(getActivity());
mInterstitialAd.setAdUnitId(interstialAd);
mInterstitialAd.loadAd(new AdRequest.Builder().build());
mInterstitialAd.setAdListener(new AdListener() {
@Override
public void onAdClosed() {
// Load the next interstitial.
Toast.makeText(getActivity(), "Thank you for supporting us, kind mate :)",
Toast.LENGTH_LONG).show();
mInterstitialAd.loadAd(new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build());
}
});
Here’s my json file:
{
"response": {
"Interstial AD": "ca-app-pub-3940256099942544/1033173712"
}
}
The issue is, not only does it not work, it crashes my app with this error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.domian.app/com.domain.app.MainActivity}: com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 7 path $
Edit: New Logs:
Stack :
==============
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:117)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
at java.net.InetAddress.getAllByName(InetAddress.java:1154)
at com.android.okhttp.Dns$1.lookup(Dns.java:39)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:244)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:26)
at java.net.URL.openStream(URL.java:1073)
at com.arewang.app.SettingsFragment.readFileFromServer(SettingsFragment.java:292)
at com.arewang.app.SettingsFragment.onCreate(SettingsFragment.java:85)
at android.support.v4.app.Fragment.performCreate(Fragment.java:2414)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1418)
at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1195)
at android.support.v4.app.FragmentTransition.calculateFragments(FragmentTransition.java:1078)
at android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:117)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2408)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2243)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:654)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:168)
at com.duolingo.open.rtlviewpager.DelegatingPagerAdapter.finishUpdate(DelegatingPagerAdapter.java:61)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1244)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1092)
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:540)
at com.duolingo.open.rtlviewpager.RtlViewPager.setAdapter(RtlViewPager.java:78)
at com.arewang.app.MainActivity.menuItemClicked(MainActivity.java:309)
at com.arewang.app.drawer.SimpleAbstractMenu.lambda$add$0(SimpleAbstractMenu.java:40)
at com.arewang.app.drawer.-$$Lambda$SimpleAbstractMenu$yY6riFac_ZFnhulwIN4yIqXEIMk.onMenuItemClick(Unknown Source:6)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:154)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
at android.support.design.internal.NavigationMenuPresenter$1.onClick(NavigationMenuPresenter.java:352)
at android.view.View.performClick(View.java:6669)
at android.view.View.performClickInternal(View.java:6638)
at android.view.View.access$3100(View.java:789)
at android.view.View$PerformClick.run(View.java:26145)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6863)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
My Fragment Full Code:
public class SettingsFragment extends PreferenceFragment implements
BillingProcessor.IBillingHandler {
//You can change this setting if you would like to disable rate-my-app
boolean HIDE_RATE_MY_APP = false;
private BillingProcessor bp;
private Preference preferencepurchase;
private AlertDialog dialog;
private static String PRODUCT_ID_BOUGHT = "item_1_bought";
public static String SHOW_DIALOG = "show_dialog";
private InterstitialAd mInterstitialAd;
private static String fileUrl = "https://drive.google.com/uc?id=113RUepiYecy5pBwj-t4BtBXwlQwgf-dU";
// Firebase
private FirebaseAnalytics mFirebaseAnalytics;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.activity_settings);
setHasOptionsMenu(true);
getContext().getTheme().applyStyle(R.style.PreferencesTheme, true);
getActivity().getTheme().applyStyle(R.style.PreferencesTheme, true);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(getActivity());
mFirebaseAnalytics.setCurrentScreen(getActivity(),"Settings Screen", null );
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setNavigationBarColor(getResources().getColor(R.color.myNavigationColor));
}
String interstialAd = new JsonParser().parse(readFileFromServer(fileUrl)).getAsJsonObject()
.get("response").getAsJsonObject()
.get("Interstial AD").getAsString();
mInterstitialAd = new InterstitialAd(getActivity());
mInterstitialAd.setAdUnitId(interstialAd);
mInterstitialAd.loadAd(new AdRequest.Builder().build());
mInterstitialAd.setAdListener(new AdListener() {
@Override
public void onAdClosed() {
// Load the next interstitial.
Toast.makeText(getActivity(), "Thank you for supporting us, kind mate :)",
Toast.LENGTH_LONG).show();
mInterstitialAd.loadAd(new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build());
}
});
// donate
Preference preferencerate = findPreference("donate");
preferencerate
.setOnPreferenceClickListener(preference -> {
CFAlertDialog.Builder builder = new CFAlertDialog.Builder(getContext())
.setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT)
.setDialogBackgroundColor(Color.parseColor("#0c0c0c"))
.setHeaderView(R.layout.support_donate_layout)
.addButton("Cancel", Color.parseColor("#0c0c0c"), Color.parseColor("#FFFFFF"), CFAlertDialog.CFAlertActionStyle.DEFAULT, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
Toast.makeText(getActivity(), "Hopefully some day you will ;)", Toast.LENGTH_LONG).show();
dialog.dismiss();
})
.addButton("Go Ahead", Color.parseColor("#FFFFFF"), Color.parseColor("#008248"), CFAlertDialog.CFAlertActionStyle.POSITIVE, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
showAD();
dialog.dismiss();
});
builder.show();
return true;
});
Preference preferencefeed = findPreference("feedback");
preferencefeed
.setOnPreferenceClickListener(preference -> {
String deviceInfo="YOUR TEXT (Edit this) nnn------------ Device Info ------------";
deviceInfo += "n Android Version: " + android.os.Build.VERSION.RELEASE;
deviceInfo += "n API Level: " + android.os.Build.VERSION.SDK_INT;
deviceInfo += "n Device: " + android.os.Build.DEVICE;
deviceInfo += "n Board: " + android.os.Build.BOARD;
deviceInfo += "n Hardware: " + android.os.Build.HARDWARE;
deviceInfo += "n Build ID: " + android.os.Build.ID;
deviceInfo += "n Device Brand: " + android.os.Build.BRAND;
deviceInfo += "n Device Manufacturer: " + android.os.Build.MANUFACTURER;
deviceInfo += "n Model (and Product): " + android.os.Build.MODEL + " ("+ android.os.Build.PRODUCT + ")";
deviceInfo += "n App Version: " + BuildConfig.VERSION_NAME;
deviceInfo += "n ---------------------------------------------";
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto","[email protected]", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "App Feedback");
emailIntent.putExtra(Intent.EXTRA_TEXT, deviceInfo);
startActivity(Intent.createChooser(emailIntent, "Send using:"));
return true;
});
Preference preferenceTweet = findPreference("tweet");
preferenceTweet
.setOnPreferenceClickListener(preference -> {
CFAlertDialog.Builder builder = new CFAlertDialog.Builder(getContext())
.setDialogStyle(CFAlertDialog.CFAlertStyle.ALERT)
.setDialogBackgroundColor(Color.parseColor("#0c0c0c"))
.setHeaderView(R.layout.support_footer_layout)
.addButton("Cancel", Color.parseColor("#0c0c0c"), Color.parseColor("#FFFFFF"), CFAlertDialog.CFAlertActionStyle.DEFAULT, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
Toast.makeText(getActivity(), "Hopefully some day you will ;)", Toast.LENGTH_LONG).show();
dialog.dismiss();
})
.addButton("Tweet", Color.parseColor("#FFFFFF"), Color.parseColor("#008248"), CFAlertDialog.CFAlertActionStyle.POSITIVE, CFAlertDialog.CFAlertActionAlignment.JUSTIFIED, (dialog, which) -> {
shareTwitter();
Toast.makeText(getActivity(), "Thank you for your support, kind mate :)", Toast.LENGTH_LONG).show();
dialog.dismiss();
});
builder.show();
return true;
});
Preference preferencelicenses = findPreference("gitlicenses");
preferencelicenses
.setOnPreferenceClickListener(preference -> {
new LicenserDialog(getContext(), R.style.AlertDialogStyle)
.setTitle("Licenses")
.setCustomNoticeTitle("Files:")
.setBackgroundColor(Color.BLACK)
.setLibrary(new Library("Android Support Libraries",
"https://developer.android.com/topic/libraries/support-library/index.html",
License.APACHE))
.setLibrary(new Library("jsoup Library",
"https://github.com/jhy/jsoup",
License.MIT))
.setLibrary(new Library("Picasso Library",
"https://github.com/square/picasso",
License.APACHE))
.setLibrary(new Library("PhotoView Library",
"https://github.com/chrisbanes/PhotoView",
License.APACHE))
.setLibrary(new Library("Calligraphy Library",
"https://github.com/chrisjenx/Calligraphy",
License.APACHE))
.setLibrary(new Library("Android Material Intro Screen Library",
"https://github.com/TangoAgency/material-intro-screen",
License.MIT))
.setLibrary(new Library("AppUpdater Library",
"https://github.com/javiersantos/AppUpdater",
License.APACHE))
.setLibrary(new Library("CFAlertDialog Library",
"https://github.com/Codigami/CFAlertDialog",
License.MIT))
.setLibrary(new Library("NoPermission Library",
"https://github.com/NoNews/NoPermission",
License.APACHE))
.setLibrary(new Library("Material About Library",
"https://github.com/jrvansuita/MaterialAbout",
License.MIT))
.setLibrary(new Library("Unsplash",
"https://unsplash.com",
License.CREATIVE_COMMONS))
.setLibrary(new Library("Flaticon",
"https://www.flaticon.com/",
License.CREATIVE_COMMONS))
.setLibrary(new Library("Licenser",
"https://github.com/marcoscgdev/Licenser",
License.MIT))
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
// TODO: 11/02/2018
})
.show();
return true;
});
if (Config.HIDE_DRAWER || !Config.DRAWER_OPEN_START) {
PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference("preferenceScreen");
Preference preferencedraweropen = findPreference("menuOpenOnStart");
preferenceScreen.removePreference(preferencedraweropen);
}
// purchase
preferencepurchase = findPreference("purchase");
String license = getResources().getString(R.string.google_play_license);
if (null != license && !license.equals("")){
bp = new BillingProcessor(getActivity(),
license, this);
bp.loadOwnedPurchasesFromGoogle();
preferencepurchase
.setOnPreferenceClickListener(preference -> {
bp.purchase(getActivity(), PRODUCT_ID());
return true;
});
if (getIsPurchased(getActivity())){
preferencepurchase.setIcon(R.drawable.ic_action_action_done);
}
} else {
PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference("preferenceScreen");
PreferenceCategory billing = (PreferenceCategory) findPreference("billing");
preferenceScreen.removePreference(billing);
}
String[] extra = getArguments().getStringArray(MainActivity.FRAGMENT_DATA);
if (null != extra && extra.length != 0 && extra[0].equals(SHOW_DIALOG)){
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Add the buttons
builder.setPositiveButton(R.string.settings_purchase, (dialog, id) -> bp.purchase(getActivity(), PRODUCT_ID()));
builder.setNegativeButton(R.string.cancel, (dialog, id) -> {
// User cancelled the dialog
});
builder.setTitle(getResources().getString(R.string.dialog_purchase_title));
builder.setMessage(getResources().getString(R.string.dialog_purchase));
// Create the AlertDialog
dialog = builder.create();
dialog.show();
}
if (HIDE_RATE_MY_APP){
PreferenceCategory other = (PreferenceCategory) findPreference("other");
Preference preference = findPreference("rate");
other.removePreference(preference);
}
}
public String readFileFromServer(String fileUrl) {
String fileContent;
try {
URL url = new URL(fileUrl);
return new Scanner(url.openStream()).useDelimiter("\A").next();
} catch (IOException e) {
throw new RuntimeException("Error while trying to read file from server!", e);
}
}
@Override
public void onBillingInitialized() {
/*
* Called when BillingProcessor was initialized and it's ready to
* purchase
*/
}
@Override
public void onProductPurchased(String productId, TransactionDetails details) {
if (productId.equals(PRODUCT_ID())){
setIsPurchased(true, getActivity());
preferencepurchase.setIcon(R.drawable.ic_action_action_done);
Toast.makeText(getActivity(), getResources().getString(R.string.settings_purchase_success), Toast.LENGTH_LONG).show();
}
Log.v("INFO", "Purchase purchased");
}
@Override
public void onBillingError(int errorCode, Throwable error) {
Toast.makeText(getActivity(), getResources().getString(R.string.settings_purchase_fail), Toast.LENGTH_LONG).show();
Log.v("INFO", "Error");
}
@Override
public void onPurchaseHistoryRestored() {
if (bp.isPurchased(PRODUCT_ID())){
setIsPurchased(true, getActivity());
Log.v("INFO", "Purchase actually restored");
preferencepurchase.setIcon(R.drawable.ic_action_action_done);
if (dialog != null) dialog.cancel();
Toast.makeText(getActivity(), getResources().getString(R.string.settings_restore_purchase_success), Toast.LENGTH_LONG).show();
}
Log.v("INFO", "Purchase restored called");
}
public void setIsPurchased(boolean purchased, Context c){
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(c);
SharedPreferences.Editor editor= prefs.edit();
editor.putBoolean(PRODUCT_ID_BOUGHT, purchased);
editor.apply();
}
public static boolean getIsPurchased(Context c){
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(c);
boolean prefson = prefs.getBoolean(PRODUCT_ID_BOUGHT, false);
return prefson;
}
private String PRODUCT_ID(){
return getResources().getString(R.string.product_id);
}
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
bp.handleActivityResult(requestCode, resultCode, intent);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.clear();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
}
@Override
public void onDestroy() {
if (bp != null)
bp.release();
super.onDestroy();
}
private void showAD() {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
} else {
requestNewInterstitial();
}
}
private void requestNewInterstitial() {
AdRequest adRequest = new AdRequest.Builder()
.build();
mInterstitialAd.loadAd(adRequest);
}
private void shareTwitter() {
String message="Share Message";
Intent tweetIntent = new Intent(Intent.ACTION_SEND);
tweetIntent.putExtra(Intent.EXTRA_TEXT, message);
tweetIntent.setType("text/plain");
PackageManager packManager = Objects.requireNonNull(getActivity()).getPackageManager();
List<ResolveInfo> resolvedInfoList = packManager.queryIntentActivities(tweetIntent, PackageManager.MATCH_DEFAULT_ONLY);
boolean resolved = false;
for (ResolveInfo resolveInfo : resolvedInfoList) {
if (resolveInfo.activityInfo.packageName.startsWith("com.twitter.android")) {
tweetIntent.setClassName(
resolveInfo.activityInfo.packageName,
resolveInfo.activityInfo.name);
resolved = true;
break;
}
}
if (resolved) {
startActivity(tweetIntent);
} else {
Intent i = new Intent();
i.putExtra(Intent.EXTRA_TEXT, message);
i.setAction(Intent.ACTION_VIEW);
i.setData(Uri.parse("https://twitter.com/intent/tweet?text=" + urlEncode(message)));
startActivity(i);
Toast.makeText(getActivity(), "No Twitter app found!", Toast.LENGTH_LONG).show();
}
}
private String urlEncode(String s) {
try {
return URLEncoder.encode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {
return "";
}
}
}
Any help would be appreciated, thanks!
2
Answers
You provided url to parse method instead of valid
JSON
. EachString
param by default is treated asJSON
. In your case you need to download content and then parse. For example:String interstitial;
See also:
You need to read that file from the server first, and then parse the result… It can be as simple as this method:
After file content is aquired, just pass it to
parse()
method.