MalformedJsonException:使用JsonReader.setLenient(true)接受格式错误的JSON-Android Studio

时间:2019-07-12 19:30:57

标签: java android json url gson

我正在尝试从JsonData获取AdMob ID到我的应用程序中,以便将来可以更改它。

我的视野:

JSON文件将被上传到我的服务器中,并且其链接将位于应用程序内部。在json文件中找到的AdMob ID应该在应用程序adUnitID中使用。到目前为止,我已经做到了:

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());
    }
});

这是我的json文件:

{
    "response": {
            "Interstial AD": "ca-app-pub-3940256099942544/1033173712"
        }
}

问题是,不仅它不起作用,而且由于以下错误使我的应用程序崩溃:

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 $

编辑:新日志:

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)

我的片段完整代码:

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) \n\n\n------------ 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","info@domain.com", 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 "";
        }
    }
}

任何帮助将不胜感激,谢谢!

2 个答案:

答案 0 :(得分:1)

您需要先从服务器读取该文件,然后解析结果...它可以像这种方法一样简单:

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);
    }
}

获取文件内容后,只需将其传递给parse()方法即可。

答案 1 :(得分:0)

您提供了解析方法的网址,而不是有效的NULL。默认情况下,每个JSON参数都被视为String。在您的情况下,您需要下载内容然后进行解析。例如: 字符串非页内广告;

JSON

另请参阅: