如何在安卓系统中检索在线ics文件中的事件?

问题描述 投票:1回答:1

我目前正在寻找一个解决方案,通过http请求访问一个在线ics文件,并在我的应用程序中使用它。我有一个想法,但我不知道如何做到这一点。我想我必须做一个get请求(也许用httpURLconnection......)来下载ics文件并保存它,然后在我的活动中使用它。我已经在我的按钮监听器的onClick方法中尝试过这种方式。

try {
    //this is the file you want to download from the remote server
    String path = "http://.../file.ics";
    //this is the name of the local file you will create
    boolean eof = false;
    URL u = new URL(path);
    HttpURLConnection c = (HttpURLConnection) u.openConnection();
    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    FileOutputStream f = new FileOutputStream(new File("data/edt.ics"));
    InputStream in = c.getInputStream();
    byte[] buffer = new byte[1024];
    int len1 = 0;
    while ((len1 = in.read(buffer)) > 0) {
        f.write(buffer, 0, len1);
    }
    f.close();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

但它在logcat中产生了这个错误。

06-02 15:29:05.260 6685-6685/com.enib.enibapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.enib.enibapp, PID: 6685
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
        at java.net.InetAddress.lookupHostByName(InetAddress.java:431)
        at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
        at java.net.InetAddress.getAllByName(InetAddress.java:215)
        at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
        at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:188)
        at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:157)
        at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:100)
        at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:357)
        at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:340)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
        at com.enib.enibapp.ui.home.HomeFragment$1.onClick(HomeFragment.java:74)
        at android.view.View.performClick(View.java:5198)
        at android.view.View$PerformClick.run(View.java:21147)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

而且我不明白这个堆栈跟踪...

目的是为了从ics文件中检索事件,以显示你在旅途中的事件。我已经找了一个解决方案来处理ics文件,我找到了iCal4j库。但是检索部分是我的一个问题。谁能帮我一下,或者给我一些线索?

PS:如果我的问题有什么问题,不要犹豫,可以向我报告问题,我是新来的,另外开始安卓开发。

android http icalendar
1个回答
0
投票

谢谢你的建议@anmari。经过一些深入的研究,我找到了问题的解释:连接请求必须放在AsyncTask的子程序的doInBackground方法中。所以我把我使用的代码放在下面,如果有人和我有同样的情况需要解决的话。

AccesHTTP类。

public class AccesHTTP extends AsyncTask<String, String, String> {
    private Controle controle;
    private String urlServ = null;
    public AsyncResponse delegate = null;

    public AccesHTTP(String servaddr) {
        controle = Controle.getInstance(null);
        urlServ = servaddr;
    }

    @Override
    protected String doInBackground(String... strings) {
        // Create a TimeZone
        System.setProperty("net.fortuna.ical4j.timezone.cache.impl", MapTimeZoneCache.class.getName());

        URL url = null;
        try {
            url = new URL(urlServ);
            Reader r = null;
            r = new InputStreamReader(url.openStream(), "ISO-8859-15");
            CalendarBuilder builder = new CalendarBuilder();
            Calendar thisCalendar = builder.build(r);
            controle.refreshEdt(thisCalendar);
        } catch (IOException | ParserException e) {
            e.printStackTrace();
        }

        return "Completed";
    }

    @Override
    protected void onPostExecute(String s){
        Log.d("Return","************ " + s + " ************");
        if(s!=null){
            delegate.processFinish(s);
        };
    }
}

AccesDistant类:

public class AccesDistant implements AsyncResponse {
    //constant
    private static final String SERVERADDR = "https://.../calendar.ics";

    public AccesDistant() {
        controle = Controle.getInstance(null);
    }

    @Override
    public void processFinish(String output) {
        if(output.equals("Completed")){
            Log.d("Completed", "*******************");
        } else {
            Log.d("Erreur null return", "*******************");
        }
    }

    public void envoi() {
        AccesHTTP dataAccess = new AccesHTTP(SERVERADDR);
        //delegate link
        dataAccess.delegate = this;
        //server call
        try {
            dataAccess.execute();
        } catch (Exception e) {
            Log.d("Erreur send request","******************" + e.toString());
            e.printStackTrace();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.