Stop current music playback, and play web streams - ANDROID - android

I have created a music player application for Android with swipe(with tabs). Whenever I'm switching to another fragment, while the music is playing and trying to play a web stream from a list, I got this error:
FATAL EXCEPTION: main
Process: com.example.npopa.musicplayern, PID: 15665
java.lang.IllegalStateException
at android.media.MediaPlayer._setAudioStreamType(Native Method)
at android.media.MediaPlayer.setAudioStreamType(MediaPlayer.java:1868)
at com.example.npopa.musicplayern.MusicService.initStreamPlayer(MusicService.java:72)
at com.example.npopa.musicplayern.RadioStreaming$2.onItemClick(RadioStreaming.java:88)
Here's my code:
package com.example.npopa.musicplayern;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import com.example.npopa.musicplayern.adapter.RadioAdapter;
import com.example.npopa.musicplayern.helpers.Streams;
import java.util.ArrayList;
public class RadioStreaming extends Fragment {
private EditText et_streamNameRS, et_streamUrlRS;
private static ArrayList<Streams> m_streamsList;
private DBHelper m_myDBHelp;
private MusicService m_musicSrv;
public static Context m_context;
private ListView m_listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.radio_streaming, container, false);
m_context = getContext();
et_streamNameRS = (EditText) rootView.findViewById(R.id.et_streamNameRS);
et_streamUrlRS = (EditText) rootView.findViewById(R.id.et_streamUrlRS);
Button bt_addStreamRS = (Button) rootView.findViewById(R.id.bt_addStreamRS);
m_listView = (ListView) rootView.findViewById(R.id.stream_listRS);
m_myDBHelp = new DBHelper();
m_streamsList = m_myDBHelp.selectStreamsList();
if (m_streamsList.isEmpty()) {
Toast.makeText(RadioStreaming.m_context, "There's no streams in DB. ADD streams!", Toast.LENGTH_LONG).show();
}
Log.d("RadioStreaming", " -------- TAG select m_streamsList ------" + m_streamsList.toString());
RadioAdapter adapt = new RadioAdapter(m_context, m_streamsList);
m_listView.setAdapter(adapt);
bt_addStreamRS.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String name = et_streamNameRS.getText().toString();
String url = et_streamUrlRS.getText().toString();
m_myDBHelp.insertStreamIntoDB(name, url);
m_listView.invalidate();
m_streamsList = null;
m_streamsList = m_myDBHelp.selectStreamsList();
RadioAdapter adapt2 = new RadioAdapter(m_context, m_streamsList);
m_listView.setAdapter(adapt2);
et_streamNameRS.setText("");
et_streamUrlRS.setText("");
}
});
m_listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if (!Functions.checkNetworkState(m_context)) {
Toast.makeText(getContext(), "Enable WIFI or Mobile Data!", Toast.LENGTH_LONG).show();
} else {
m_musicSrv = MusicService.getInstance();
if (MusicService.m_player != null) {
if (m_musicSrv.isPlaying()) {
if (m_musicSrv.is_playing_music) {
new SongDetails().stopHandler();
MusicService.m_player.stop();
MusicService.m_player.reset(); //It requires again setDataSource for player object.
// MusicService.m_player.stop();
MusicService.m_player.release();
// MusicService.m_player = null; // Initilize to null so it can be used later
m_musicSrv.initStreamPlayer(m_context);
m_musicSrv.setStreamList(m_streamsList);
m_musicSrv.setStream(Integer.parseInt(view.getTag().toString()));
m_musicSrv.playStream();
}
else {
MusicService.m_player.reset();
m_musicSrv.initStreamPlayer(m_context);
m_musicSrv.setStreamList(m_streamsList);
m_musicSrv.setStream(Integer.parseInt(view.getTag().toString()));
m_musicSrv.playStream();
}
}
else {
m_musicSrv.initStreamPlayer(m_context);
m_musicSrv.setStreamList(m_streamsList);
m_musicSrv.setStream(Integer.parseInt(view.getTag().toString()));
m_musicSrv.playStream();
}
}
else {
m_musicSrv.initStreamPlayer(m_context);
m_musicSrv.setStreamList(m_streamsList);
m_musicSrv.setStream(Integer.parseInt(view.getTag().toString()));
m_musicSrv.playStream();
}
}
}
});
return rootView;
}
}
package com.example.npopa.musicplayern;
import android.content.ContentUris;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.PowerManager;
import android.util.Log;
import android.widget.Toast;
import com.example.npopa.musicplayern.helpers.Streams;
import com.example.npopa.musicplayern.helpers.Song;
import java.util.ArrayList;
import java.util.Random;
public class MusicService implements MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener {
public static MediaPlayer m_player;
public static String m_songTitle = "";
public static String m_artistName = "";
private static String m_streamNAME, m_streamURL;
public static Bitmap m_albumImageMS;
public static ArrayList<Song> m_songs;
public static ArrayList<Streams> m_streams;
public static int m_songPosn;
public static int m_streamPosition;
private static int m_streamID;
public static boolean m_shuffle = false;
public static boolean m_repeat = false;
public boolean is_playing_music = false;
public boolean is_playing_streams = false;
private Random m_rand;
private DBHelper m_db;
private static MusicService myService = new MusicService();
// a private Constructor prevents any other class from instantiating
private MusicService() {
}
public static MusicService getInstance() {
if (myService == null) {
myService = new MusicService();
}
return myService;
}
public void initSongPlayer(Context context) {
m_songs = new ArrayList<Song>();
m_songPosn = 0;
if (m_player == null) {
m_player = new MediaPlayer();
}
m_player.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
m_player.setAudioStreamType(AudioManager.STREAM_MUSIC);
m_player.setOnPreparedListener(this);
m_player.setOnCompletionListener(this);
m_player.setOnErrorListener(this);
}
public void initStreamPlayer(Context context) {
m_streams = new ArrayList<Streams>();
m_streamPosition = 0;
if (m_player == null) {
m_player = new MediaPlayer();
}
m_player.setOnPreparedListener(this);
m_player.setOnBufferingUpdateListener(this);
m_player.setOnErrorListener(this);
m_player.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
m_player.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
public void setSong(int songIndex) {
m_songPosn = songIndex;
}
public void setSongList(ArrayList<Song> theSongs) {
Log.d("MusicService", "setSongList() - playlist nou marime: " + theSongs.size());
if (theSongs.size() > 0){
m_songs = theSongs;
m_db = new DBHelper();
m_db.deleteAllSongsPlaylist();
m_db.setSongsLastPlaylist(m_songs);
}
}
public void setStream(int streamIndex) {
m_streamPosition = streamIndex;
}
public void setStreamList(ArrayList<Streams> theStreams) {
m_streams = theStreams;
}
public void playSong(Context context) {
if(m_songs.size() == 0) {
Log.d("MusicService", "playSong() - playlist 0 elemente");
}
else {
is_playing_music = true;
is_playing_streams = false;
m_player.reset();
Song playSong = m_songs.get(m_songPosn);
m_songTitle = playSong.getTitle();
m_artistName = playSong.getArtist();
m_albumImageMS = playSong.getAlbumImage();
long currSong = playSong.getID();
Log.d("MusicService", "---------------------CURRENT SONG ID " + String.valueOf(currSong));
Uri trackUri = ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, currSong);
try {
m_player.setDataSource(context, trackUri);
} catch (Exception e) {
Log.e("MusicService", "Error setting data source", e);
}
m_player.prepareAsync();
m_db = new DBHelper();
m_db.updatePlayerInfo(String.valueOf(currSong), 1);
}
}
public void playStream() {
is_playing_music = false;
is_playing_streams = true;
m_player.reset();
Streams currStream = m_streams.get(m_streamPosition);
m_streamID = currStream.getId();
m_streamNAME = currStream.getName();
m_streamURL = currStream.getUrl();
try { // http://usa8-vn.mixstream.net:8138
m_player.setDataSource(m_streamURL);
Log.d("MusicService", "------------------ playStream() ---------------------" + m_streamURL);
} catch (Exception e) {
// e.printStackTrace();
Log.d("MusicService", "---------- Error setting stream data source", e);
}
m_player.prepareAsync();
DBHelper dbhelp = new DBHelper();
dbhelp.updatePlayerInfo(String.valueOf(m_streamID), 0);
}
public Bitmap getAlbumImageMS() {
return m_albumImageMS;
}
public String getMusicTitle() {
return m_songTitle;
}
public String getMusicArtist() {
return m_artistName;
}
public int getCurrentPosition() {
return m_player.getCurrentPosition();
}
public int getDuration() {
return m_player.getDuration();
}
public boolean isPlaying() {
if (m_player == null){
return false;
}
else {
return m_player.isPlaying();
}
}
public void seekTO(int posn) {
m_player.seekTo(posn);
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
if (is_playing_streams) {
Toast.makeText(MainActivity.m_context, "Playback Error - INVALID URL", Toast.LENGTH_LONG).show();
}
Log.v("MusicService", "Playback Error");
mp.reset();
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
if (m_player.getCurrentPosition() > 0) {
mp.reset();
playNextSong();
}
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
if (is_playing_music) {
Log.d("MusicService", "---------- Playing MUSIC--- :" + getMusicTitle() + " - - by - - " + getMusicArtist());
}
else if (is_playing_streams) {
Toast.makeText(MainActivity.m_context, "Playing STREAM:" + m_streamNAME + " from " + m_streamURL, Toast.LENGTH_LONG).show();
Log.d("MusicService", "---------- Playing STREAM:" + m_streamNAME + " from " + m_streamURL);
}
}
#Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int percent) {
Log.d("MusicService", "---------- Buffering " + percent);
Toast.makeText(MainActivity.m_context, "Buffering: " + percent, Toast.LENGTH_LONG).show();
}
public void playNextSong() {
m_rand = new Random();
if (m_repeat == true) {
int pos1 = m_songPosn;
m_songPosn = pos1;
} else if (m_shuffle == true) {
int newSong = m_songPosn;
while (newSong == m_songPosn) {
newSong = m_rand.nextInt(m_songs.size());
}
m_songPosn = newSong;
} else if (m_repeat == true && m_shuffle == true) {
int pos2 = m_songPosn;
m_songPosn = pos2;
} else {
////////////////////////////////////////////
m_songPosn++;
if (m_songPosn >= m_songs.size()) {
m_songPosn = 0;
}
}
playSong(MainActivity.m_context);
}
public void playPrevSong() {
if (m_shuffle == true) {
int newSong = m_songPosn;
while (newSong == m_songPosn) {
newSong = m_rand.nextInt(m_songs.size());
}
m_songPosn = newSong;
} else {
m_songPosn--;
if (m_songPosn < 0) {
m_songPosn = m_songs.size() - 1;
}
}
playSong(MainActivity.m_context);
}
public void playNextStream() {
m_streamPosition++;
if (m_streamPosition >= m_streams.size()) {
m_streamPosition = 1;
}
playStream();
}
public void playPrevStream() {
m_streamPosition--;
if (m_streamPosition < 1) {
m_streamPosition = m_streams.size() - 1;
}
playStream();
}
}
Every kind of help is appreciated. Thanks in advance.

Related

Android get attribute value from xml

I am trying to make an app which uses last.fm's web API, sends a query for similar artists and returns all the names of the similar artists. It seems as though I manage to connect and get the xml response properly. However, I cannot extract the value of the name-attribute. I am using artistName = xmlData.getAttributeValue(null, "name"); but all it gives me is null.
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.*;
#SuppressWarnings("FieldCanBeLocal")
public class MainActivity extends Activity implements Observer {
private final String INPUTERROR = "Invalid/missing artist name.";
private NetworkCommunication nc;
private ArrayList<String> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nc = new NetworkCommunication();
nc.register(this);
list = new ArrayList<>();
ListView lv = (ListView)findViewById(R.id.ListView_similarArtistsList);
ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, list);
lv.setAdapter(adapter);
}
public void searchButton_Clicked(View v){
EditText inputField = (EditText)findViewById(R.id.editText_artistName);
String searchString = inputField.getText().toString();
searchString = cleanSearchString(searchString);
if(validateSearchString(searchString)){
nc.setSearchString(searchString);
nc.execute();
}
else{
Toast.makeText(MainActivity.this, INPUTERROR, Toast.LENGTH_SHORT).show();
}
}
private String cleanSearchString(String oldSearchString){
String newString = oldSearchString.trim();
newString = newString.replace(" ", "");
return newString;
}
private boolean validateSearchString(String searchString){
boolean rValue = true;
if(TextUtils.isEmpty(searchString)){
rValue = false;
}
return rValue;
}
#Override
public void update(String artistName) {
list.add(artistName);
}
}
Here is my Network Communications class:
import android.os.AsyncTask;
import android.util.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
#SuppressWarnings("FieldCanBeLocal")
class NetworkCommunication extends AsyncTask<Object, String, Integer> implements Subject {
private final String MYAPIKEY = "--------------------------";
private final String ROOT = "http://ws.audioscrobbler.com/2.0/";
private final String METHOD = "?method=artist.getsimilar";
private ArrayList<Observer> observers;
private int amountOfArtists = 0;
private String foundArtistName;
private String searchString;
NetworkCommunication(){
observers = new ArrayList<>();
}
void setSearchString(String newSearchString){
searchString = newSearchString;
}
private XmlPullParser sendRequest(){
try{
URL url = new URL(ROOT + METHOD + "&artist=" + searchString + "&api_key=" + MYAPIKEY);
XmlPullParser receivedData = XmlPullParserFactory.newInstance().newPullParser();
receivedData.setInput(url.openStream(), null);
return receivedData;
}
catch (IOException | XmlPullParserException e){
Log.e("ERROR", e.getMessage(), e);
}
return null;
}
private int tryProcessData(XmlPullParser xmlData){
int artistsFound = 0;
String artistName;
int eventType;
try{
while ((eventType = xmlData.next()) != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if(xmlData.getName().equals("name")){
artistName = xmlData.getAttributeValue(null, "name");
publishProgress(artistName);
artistsFound++;
}
}
}
}
catch (IOException | XmlPullParserException e){
Log.e("ERROR", e.getMessage(), e);
}
if (artistsFound == 0) {
publishProgress();
}
return artistsFound;
}
#Override
protected Integer doInBackground(Object... params) {
XmlPullParser data = sendRequest();
if(data != null){
return tryProcessData(data);
}
else{
return null;
}
}
#Override
protected void onProgressUpdate(String... values){
/*
if (values.length == 0) {
//No data found...
}
*/
if (values.length == 1) {
setFoundArtistName(values[0]);
notifyObserver();
}
super.onProgressUpdate(values);
}
private void setFoundArtistName(String newArtistName){
foundArtistName = newArtistName;
}
#Override
public void register(Observer newObserver) {
observers.add(newObserver);
}
#Override
public void unregister(Observer deleteObserver) {
observers.remove(deleteObserver);
}
#Override
public void notifyObserver() {
for (Observer o : observers) {
Log.i("my tag.... ", "name = " + foundArtistName);
o.update(foundArtistName);
}
}
}
Here's a screenshot of the xml response in Google Chrome:
The only thing I am interested in extracting at this moment is the the value of the Name-Element.
I am logging the value of foundArtistName (in the method notifyObserver) it gives me A LOT of "my tag.... name = null my tag.... name = null my tag.... name = null etc.."
EDIT: I tried using getText() instead of getAttributeValue(), but it also gives me null.
I found the solution. I was using: artistName = xmlData.getAttributeValue(null, "name");, when I really should've used: artistName = xmlData.nextText();

How can I setAllowFileAccess for a react-native android WebView?

I want to disable file access within an Android WebView I'm creating using react-native's built-in WebView component.
The Android WebView docs say "File access is enabled by default.", and this is a security concern for my organization.
The react-native 0.31 docs mention a getWebViewHandle method that can be used to access the underlying WebView node; if this worked, then I could (presumably) write:
import { WebView, Platform } from 'react-native';
//...
var reactWebview = <Webview [props here] />
if (Platform.OS === 'android') {
var webview = reactWebview.getWebViewHandle();
webview.setAllowFileAccess(false);
}
However, later versions of the react-native docs don't mention getWebViewHandle, and when I run code like this in react-native 0.44 on an Android device, I get the error webview.getWebViewHandle is not a function.
My questions are:
Is file access enabled by default for the Android WebViews created by react-native?
If so, how can we disable this file access? Could we accomplish this by extending the WebView class, or would we need to fork and modify react-native?
Thanks for your time!
Questions 1: As see from the source code of ReactWebViewManager.java, RN does not call WebView.setAllowFileAccess, so file access is enabled by Android WebView, not by RN.
Questions 2: You can create a custom WebView to do what you need, or just get the reference of your WebView from a Native Module, then you can access all the apis of Android WebView like setAllowFileAccess in that Native Module.
Native Module
public class WebViewSettingModule extends ReactContextBaseJavaModule {
public WebViewSettingModule(ReactApplicationContext reactContext) {
super(reactContext);
}
#Override
public String getName() {
return "WebViewSetting";
}
#ReactMethod
public void setWebView() {
Activity activity = getCurrentActivity();
//the id for the ReactRootView is always be 1
#IdRes int id = 1;
View view = activity.findViewById(id);
if (view instanceof ReactRootView) {
ReactRootView reactRootView = (ReactRootView) view;
//make sure the WebView is directly child of ReactRootView
reactRootView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
#Override
public void onChildViewAdded(View parent, final View child) {
if (child instanceof WebView) {
Log.e("onChildViewAdded: ", ((WebView) child).getUrl());
//get the reference to the WebView and setAllowFileAccess
((WebView) child).getSettings().setAllowFileAccess(false);
}
}
#Override
public void onChildViewRemoved(View parent, View child) {
}
});
}
}
}
index.android.js
import React, {Component} from "react";
import {AppRegistry, View, WebView} from "react-native";
//the native module
import MyWebView from "./src/MyWebView";
export default class WebViewSetting extends Component {
componentDidMount() {
//notify native code to modify WebView setting
MyWebView.setWebView();
}
render() {
return (
<View style={{flex: 1}}>
<WebView
source={{uri: 'https://github.com/'}}
style={{marginTop: 20}}/>
</View>
);
}
}
AppRegistry.registerComponent('WebViewSetting', () => WebViewSetting);
the whole code can be found here
node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/views/ReactWebViewManager.java
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.views.webview;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Picture;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.ViewGroup.LayoutParams;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.ContentSizeChangeEvent;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.webview.events.TopLoadingErrorEvent;
import com.facebook.react.views.webview.events.TopLoadingFinishEvent;
import com.facebook.react.views.webview.events.TopLoadingStartEvent;
import com.facebook.react.views.webview.events.TopMessageEvent;
import org.json.JSONObject;
import org.json.JSONException;
#ReactModule(name = ReactWebViewManager.REACT_CLASS)
public class ReactWebViewManager extends SimpleViewManager<WebView> {
protected static final String REACT_CLASS = "RCTWebView";
private static final String HTML_ENCODING = "UTF-8";
private static final String HTML_MIME_TYPE = "text/html; charset=utf-8";
private static final String BRIDGE_NAME = "__REACT_WEB_VIEW_BRIDGE";
private static final String HTTP_METHOD_POST = "POST";
public static final int COMMAND_GO_BACK = 1;
public static final int COMMAND_GO_FORWARD = 2;
public static final int COMMAND_RELOAD = 3;
public static final int COMMAND_STOP_LOADING = 4;
public static final int COMMAND_POST_MESSAGE = 5;
public static final int COMMAND_INJECT_JAVASCRIPT = 6;
private static final String BLANK_URL = "about:blank";
public static final int INPUT_FILE_REQUEST_GALLERY_IMAGE = 1001;
public static final int REQUEST_SELECT_FILE_LEGACY = 1012;
private WebViewConfig mWebViewConfig;
private
#Nullable
WebView.PictureListener mPictureListener;
private ValueCallback<Uri[]> mFilePathCallbackArr;
private ValueCallback<Uri> mFilePathCallback; // Legacy (Android 4.1+)
private String mCameraPhotoPath;
protected static class ReactWebViewClient extends WebViewClient {
private boolean mLastLoadFailed = false;
#Override
public void onPageFinished(WebView webView, String url) {
super.onPageFinished(webView, url);
if (!mLastLoadFailed) {
ReactWebView reactWebView = (ReactWebView) webView;
reactWebView.callInjectedJavaScript();
reactWebView.linkBridge();
emitFinishEvent(webView, url);
}
}
#Override
public void onPageStarted(WebView webView, String url, Bitmap favicon) {
super.onPageStarted(webView, url, favicon);
mLastLoadFailed = false;
dispatchEvent(
webView,
new TopLoadingStartEvent(
webView.getId(),
createWebViewEvent(webView, url)));
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("http://") || url.startsWith("https://") ||
url.startsWith("file://")) {
return false;
} else {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
view.getContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
FLog.w(ReactConstants.TAG, "activity not found to handle uri scheme for: " + url, e);
}
return true;
}
}
#Override
public void onReceivedError(
WebView webView,
int errorCode,
String description,
String failingUrl) {
super.onReceivedError(webView, errorCode, description, failingUrl);
mLastLoadFailed = true;
emitFinishEvent(webView, failingUrl);
WritableMap eventData = createWebViewEvent(webView, failingUrl);
eventData.putDouble("code", errorCode);
eventData.putString("description", description);
dispatchEvent(
webView,
new TopLoadingErrorEvent(webView.getId(), eventData));
}
#Override
public void doUpdateVisitedHistory(WebView webView, String url, boolean isReload) {
super.doUpdateVisitedHistory(webView, url, isReload);
dispatchEvent(
webView,
new TopLoadingStartEvent(
webView.getId(),
createWebViewEvent(webView, url)));
}
private void emitFinishEvent(WebView webView, String url) {
dispatchEvent(
webView,
new TopLoadingFinishEvent(
webView.getId(),
createWebViewEvent(webView, url)));
}
private WritableMap createWebViewEvent(WebView webView, String url) {
WritableMap event = Arguments.createMap();
event.putDouble("target", webView.getId());
event.putString("url", url);
event.putBoolean("loading", !mLastLoadFailed && webView.getProgress() != 100);
event.putString("title", webView.getTitle());
event.putBoolean("canGoBack", webView.canGoBack());
event.putBoolean("canGoForward", webView.canGoForward());
return event;
}
}
protected static class ReactWebView extends WebView implements LifecycleEventListener {
private
#Nullable
String injectedJS;
private boolean messagingEnabled = false;
private class ReactWebViewBridge {
ReactWebView mContext;
ReactWebViewBridge(ReactWebView c) {
mContext = c;
}
#JavascriptInterface
public void postMessage(String message) {
mContext.onMessage(message);
}
}
public ReactWebView(ThemedReactContext reactContext) {
super(reactContext);
}
#Override
public void onHostResume() {
// do nothing
}
#Override
public void onHostPause() {
// do nothing
}
#Override
public void onHostDestroy() {
cleanupCallbacksAndDestroy();
}
public void setInjectedJavaScript(#Nullable String js) {
injectedJS = js;
}
public void setMessagingEnabled(boolean enabled) {
if (messagingEnabled == enabled) {
return;
}
messagingEnabled = enabled;
if (enabled) {
addJavascriptInterface(new ReactWebViewBridge(this), BRIDGE_NAME);
linkBridge();
} else {
removeJavascriptInterface(BRIDGE_NAME);
}
}
public void callInjectedJavaScript() {
if (getSettings().getJavaScriptEnabled() &&
injectedJS != null &&
!TextUtils.isEmpty(injectedJS)) {
loadUrl("javascript:(function() {\n" + injectedJS + ";\n})();");
}
}
public void linkBridge() {
if (messagingEnabled) {
if (ReactBuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// See isNative in lodash
String testPostMessageNative = "String(window.postMessage) === String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage')";
evaluateJavascript(testPostMessageNative, new ValueCallback<String>() {
#Override
public void onReceiveValue(String value) {
if (value.equals("true")) {
FLog.w(ReactConstants.TAG, "Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined");
}
}
});
}
loadUrl("javascript:(" +
"window.originalPostMessage = window.postMessage," +
"window.postMessage = function(data) {" +
BRIDGE_NAME + ".postMessage(String(data));" +
"}" +
")");
}
}
public void onMessage(String message) {
dispatchEvent(this, new TopMessageEvent(this.getId(), message));
}
private void cleanupCallbacksAndDestroy() {
setWebViewClient(null);
destroy();
}
}
public ReactWebViewManager() {
mWebViewConfig = new WebViewConfig() {
public void configWebView(WebView webView) {
}
};
}
public ReactWebViewManager(WebViewConfig webViewConfig) {
mWebViewConfig = webViewConfig;
}
#Override
public String getName() {
return REACT_CLASS;
}
#Override
protected WebView createViewInstance(final ThemedReactContext reactContext) {
ReactWebView webView = new ReactWebView(reactContext);
webView.setWebChromeClient(new WebChromeClient() {
#Override
public boolean onConsoleMessage(ConsoleMessage message) {
if (ReactBuildConfig.DEBUG) {
return super.onConsoleMessage(message);
}
return true;
}
#Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File imageFile = new File(
storageDir,
imageFileName + ".jpg"
);
return imageFile;
}
private Intent getVideoCaptureIntent() {
Intent recordVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
recordVideoIntent
.resolveActivity(
reactContext
.getCurrentActivity()
.getPackageManager()
);
recordVideoIntent.putExtra("type", "foobar");
return recordVideoIntent;
}
public boolean onShowFileChooser(
WebView webView,
ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams
) {
if (mFilePathCallbackArr != null) {
mFilePathCallbackArr.onReceiveValue(null);
}
mFilePathCallbackArr = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
ComponentName comp = takePictureIntent
.resolveActivity(
reactContext
.getCurrentActivity()
.getPackageManager()
);
if (comp != null) {
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
FLog.e(ReactConstants.TAG, "Unable to create Image File", ex);
}
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("*/*");
Intent videoCaptureIntent = getVideoCaptureIntent();
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}
intentArray = new Intent[]{
intentArray[0],
videoCaptureIntent
};
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
reactContext.getCurrentActivity().startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_GALLERY_IMAGE);
return true;
}
});
reactContext.addLifecycleEventListener(webView);
reactContext.addActivityEventListener(new ActivityEventListener() {
// Android 5+
#Override
public void onActivityResult (Activity activity, int requestCode, int resultCode, Intent data) {
if(requestCode != INPUT_FILE_REQUEST_GALLERY_IMAGE || mFilePathCallbackArr == null) {
return;
}
Uri[] results = null;
if(resultCode == Activity.RESULT_OK) {
if(data == null || data.getData() == null) {
if(mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
if(results == null) {
mFilePathCallbackArr.onReceiveValue(new Uri[]{});
}
else {
mFilePathCallbackArr.onReceiveValue(results);
}
mFilePathCallbackArr = null;
return;
}
#Override
public void onNewIntent(Intent intent) {}
});
mWebViewConfig.configWebView(webView);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setDisplayZoomControls(false);
webView.getSettings().setDomStorageEnabled(true);
webView.setLayoutParams(
new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
if (ReactBuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
return webView;
}
#ReactProp(name = "javaScriptEnabled")
public void setJavaScriptEnabled(WebView view, boolean enabled) {
view.getSettings().setJavaScriptEnabled(enabled);
}
#ReactProp(name = "scalesPageToFit")
public void setScalesPageToFit(WebView view, boolean enabled) {
view.getSettings().setUseWideViewPort(!enabled);
}
#ReactProp(name = "domStorageEnabled")
public void setDomStorageEnabled(WebView view, boolean enabled) {
view.getSettings().setDomStorageEnabled(enabled);
}
#ReactProp(name = "userAgent")
public void setUserAgent(WebView view, #Nullable String userAgent) {
if (userAgent != null) {
// TODO(8496850): Fix incorrect behavior when property is unset (uA == null)
view.getSettings().setUserAgentString(userAgent);
}
}
#ReactProp(name = "mediaPlaybackRequiresUserAction")
public void setMediaPlaybackRequiresUserAction(WebView view, boolean requires) {
view.getSettings().setMediaPlaybackRequiresUserGesture(requires);
}
#ReactProp(name = "allowUniversalAccessFromFileURLs")
public void setAllowUniversalAccessFromFileURLs(WebView view, boolean allow) {
view.getSettings().setAllowUniversalAccessFromFileURLs(allow);
}
#ReactProp(name = "injectedJavaScript")
public void setInjectedJavaScript(WebView view, #Nullable String injectedJavaScript) {
((ReactWebView) view).setInjectedJavaScript(injectedJavaScript);
}
#ReactProp(name = "messagingEnabled")
public void setMessagingEnabled(WebView view, boolean enabled) {
((ReactWebView) view).setMessagingEnabled(enabled);
}
#ReactProp(name = "source")
public void setSource(WebView view, #Nullable ReadableMap source) {
if (source != null) {
if (source.hasKey("html")) {
String html = source.getString("html");
if (source.hasKey("baseUrl")) {
view.loadDataWithBaseURL(
source.getString("baseUrl"), html, HTML_MIME_TYPE, HTML_ENCODING, null);
} else {
view.loadData(html, HTML_MIME_TYPE, HTML_ENCODING);
}
return;
}
if (source.hasKey("uri")) {
String url = source.getString("uri");
String previousUrl = view.getUrl();
if (previousUrl != null && previousUrl.equals(url)) {
return;
}
if (source.hasKey("method")) {
String method = source.getString("method");
if (method.equals(HTTP_METHOD_POST)) {
byte[] postData = null;
if (source.hasKey("body")) {
String body = source.getString("body");
try {
postData = body.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
postData = body.getBytes();
}
}
if (postData == null) {
postData = new byte[0];
}
view.postUrl(url, postData);
return;
}
}
HashMap<String, String> headerMap = new HashMap<>();
if (source.hasKey("headers")) {
ReadableMap headers = source.getMap("headers");
ReadableMapKeySetIterator iter = headers.keySetIterator();
while (iter.hasNextKey()) {
String key = iter.nextKey();
if ("user-agent".equals(key.toLowerCase(Locale.ENGLISH))) {
if (view.getSettings() != null) {
view.getSettings().setUserAgentString(headers.getString(key));
}
} else {
headerMap.put(key, headers.getString(key));
}
}
}
view.loadUrl(url, headerMap);
return;
}
}
view.loadUrl(BLANK_URL);
}
#ReactProp(name = "onContentSizeChange")
public void setOnContentSizeChange(WebView view, boolean sendContentSizeChangeEvents) {
if (sendContentSizeChangeEvents) {
view.setPictureListener(getPictureListener());
} else {
view.setPictureListener(null);
}
}
#ReactProp(name = "mixedContentMode")
public void setMixedContentMode(WebView view, #Nullable String mixedContentMode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (mixedContentMode == null || "never".equals(mixedContentMode)) {
view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW);
} else if ("always".equals(mixedContentMode)) {
view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
} else if ("compatibility".equals(mixedContentMode)) {
view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
}
}
}
#Override
protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
view.setWebViewClient(new ReactWebViewClient());
}
#Override
public
#Nullable
Map<String, Integer> getCommandsMap() {
return MapBuilder.of(
"goBack", COMMAND_GO_BACK,
"goForward", COMMAND_GO_FORWARD,
"reload", COMMAND_RELOAD,
"stopLoading", COMMAND_STOP_LOADING,
"postMessage", COMMAND_POST_MESSAGE,
"injectJavaScript", COMMAND_INJECT_JAVASCRIPT
);
}
#Override
public void receiveCommand(WebView root, int commandId, #Nullable ReadableArray args) {
switch (commandId) {
case COMMAND_GO_BACK:
root.goBack();
break;
case COMMAND_GO_FORWARD:
root.goForward();
break;
case COMMAND_RELOAD:
root.reload();
break;
case COMMAND_STOP_LOADING:
root.stopLoading();
break;
case COMMAND_POST_MESSAGE:
try {
JSONObject eventInitDict = new JSONObject();
eventInitDict.put("data", args.getString(0));
root.loadUrl("javascript:(function () {" +
"var event;" +
"var data = " + eventInitDict.toString() + ";" +
"try {" +
"event = new MessageEvent('message', data);" +
"} catch (e) {" +
"event = document.createEvent('MessageEvent');" +
"event.initMessageEvent('message', true, true, data.data, data.origin, data.lastEventId, data.source);" +
"}" +
"document.dispatchEvent(event);" +
"})();");
} catch (JSONException e) {
throw new RuntimeException(e);
}
break;
case COMMAND_INJECT_JAVASCRIPT:
root.loadUrl("javascript:" + args.getString(0));
break;
}
}
#Override
public void onDropViewInstance(WebView webView) {
super.onDropViewInstance(webView);
((ThemedReactContext) webView.getContext()).removeLifecycleEventListener((ReactWebView) webView);
((ReactWebView) webView).cleanupCallbacksAndDestroy();
}
private WebView.PictureListener getPictureListener() {
if (mPictureListener == null) {
mPictureListener = new WebView.PictureListener() {
#Override
public void onNewPicture(WebView webView, Picture picture) {
dispatchEvent(
webView,
new ContentSizeChangeEvent(
webView.getId(),
webView.getWidth(),
webView.getContentHeight()));
}
};
}
return mPictureListener;
}
private static void dispatchEvent(WebView webView, Event event) {
ReactContext reactContext = (ReactContext) webView.getContext();
EventDispatcher eventDispatcher =
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
eventDispatcher.dispatchEvent(event);
}
}
I could not find this solution anywhere so I thought I would share, I hope it helps...
To enable the browse button to work and subsequently allow file access you can replace the above and this react-native files with these modified versions:
node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.uimanager;
import javax.annotation.Nullable;
import android.app.Activity;
import android.content.Context;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.LifecycleEventListener;
//
/**
* Wraps {#link ReactContext} with the base {#link Context} passed into the constructor.
* It provides also a way to start activities using the viewContext to which RN native views belong.
* It delegates lifecycle listener registration to the original instance of {#link ReactContext}
* which is supposed to receive the lifecycle events. At the same time we disallow receiving
* lifecycle events for this wrapper instances.
* TODO: T7538544 Rename ThemedReactContext to be in alignment with name of ReactApplicationContext
*/
public class ThemedReactContext extends ReactContext {
private final ReactApplicationContext mReactApplicationContext;
public ThemedReactContext(ReactApplicationContext reactApplicationContext, Context base) {
super(base);
initializeWithInstance(reactApplicationContext.getCatalystInstance());
mReactApplicationContext = reactApplicationContext;
}
#Override
public void addLifecycleEventListener(LifecycleEventListener listener) {
mReactApplicationContext.addLifecycleEventListener(listener);
}
#Override
public void removeLifecycleEventListener(LifecycleEventListener listener) {
mReactApplicationContext.removeLifecycleEventListener(listener);
}
#Override
public void addActivityEventListener(ActivityEventListener listener) {
mReactApplicationContext.addActivityEventListener(listener);
}
#Override
public void removeActivityEventListener(ActivityEventListener listener) {
mReactApplicationContext.removeActivityEventListener(listener);
}
#Override
public boolean hasCurrentActivity() {
return mReactApplicationContext.hasCurrentActivity();
}
#Override
public
#Nullable
Activity getCurrentActivity() {
return mReactApplicationContext.getCurrentActivity();
}
}
The second file is listed above

Telegram API RPC Timeout Exception

I am using telegram API to develop my application. Here is the whole code.
app_info.java:
package com.example.mytelegram;
import org.telegram.api.engine.AppInfo;
public class app_info extends AppInfo {
public app_info(int apiId, String deviceModel, String systemVersion,
String appVersion, String langCode) {
super(apiId, deviceModel, systemVersion, appVersion, langCode);
// TODO Auto-generated constructor stub
}
MemoryApiState.java:
package com.example.mytelegram;
import org.telegram.api.TLConfig;
import org.telegram.api.TLDcOption;
import org.telegram.api.engine.storage.AbsApiState;
import org.telegram.mtproto.state.AbsMTProtoState;
import org.telegram.mtproto.state.ConnectionInfo;
import org.telegram.mtproto.state.KnownSalt;
import java.util.ArrayList;
import java.util.HashMap;
public class MemoryApiState implements AbsApiState {
private HashMap<Integer, ConnectionInfo[]> connections = new HashMap<Integer, ConnectionInfo[]>();
private HashMap<Integer, byte[]> keys = new HashMap<Integer, byte[]>();
private HashMap<Integer, Boolean> isAuth = new HashMap<Integer, Boolean>();
private int primaryDc = 2; // I have tested application with primaryDc=0 to 10
public MemoryApiState(boolean isTest) {
connections.put(1, new ConnectionInfo[]{
new ConnectionInfo(1, 0, isTest ? "149.154.167.40" : "149.154.167.50", 443)
});
}
#Override
public synchronized int getPrimaryDc() {
return primaryDc;
}
#Override
public synchronized void setPrimaryDc(int dc) {
primaryDc = dc;
}
#Override
public synchronized boolean isAuthenticated(int dcId) {
if (isAuth.containsKey(dcId)) {
return isAuth.get(dcId);
}
return false;
}
#Override
public synchronized void setAuthenticated(int dcId, boolean auth) {
isAuth.put(dcId, auth);
}
#Override
public synchronized void updateSettings(TLConfig config) {
connections.clear();
HashMap<Integer, ArrayList<ConnectionInfo>> tConnections = new HashMap<Integer, ArrayList<ConnectionInfo>>();
int id = 0;
for (TLDcOption option : config.getDcOptions()) {
if (!tConnections.containsKey(option.getId())) {
tConnections.put(option.getId(), new ArrayList<ConnectionInfo>());
}
tConnections.get(option.getId()).add(new ConnectionInfo(id++, 0, option.getIpAddress(), option.getPort()));
}
for (Integer dc : tConnections.keySet()) {
connections.put(dc, tConnections.get(dc).toArray(new ConnectionInfo[0]));
}
}
#Override
public synchronized byte[] getAuthKey(int dcId) {
return keys.get(dcId);
}
#Override
public synchronized void putAuthKey(int dcId, byte[] key) {
keys.put(dcId, key);
}
#Override
public synchronized ConnectionInfo[] getAvailableConnections(int dcId) {
if (!connections.containsKey(dcId)) {
return new ConnectionInfo[0];
}
return connections.get(dcId);
}
#Override
public synchronized AbsMTProtoState getMtProtoState(final int dcId) {
return new AbsMTProtoState() {
private KnownSalt[] knownSalts = new KnownSalt[0];
#Override
public byte[] getAuthKey() {
return MemoryApiState.this.getAuthKey(dcId);
}
#Override
public ConnectionInfo[] getAvailableConnections() {
return MemoryApiState.this.getAvailableConnections(dcId);
}
#Override
public KnownSalt[] readKnownSalts() {
return knownSalts;
}
#Override
protected void writeKnownSalts(KnownSalt[] salts) {
knownSalts = salts;
}
};
}
#Override
public synchronized void resetAuth() {
isAuth.clear();
}
#Override
public synchronized void reset() {
isAuth.clear();
keys.clear();
}
}
MainActivity.java:
package com.example.mytelegram;
import java.io.IOException;
import org.telegram.api.TLAbsUpdates;
import org.telegram.api.TLConfig;
import org.telegram.api.TLNearestDc;
import org.telegram.api.auth.TLAuthorization;
import org.telegram.api.auth.TLSentCode;
import org.telegram.api.engine.ApiCallback;
import org.telegram.api.engine.AppInfo;
import org.telegram.api.engine.LoggerInterface;
import org.telegram.api.engine.RpcException;
import org.telegram.api.engine.TelegramApi;
import org.telegram.api.requests.TLRequestAuthSendCall;
import org.telegram.api.requests.TLRequestAuthSendCode;
import org.telegram.api.requests.TLRequestAuthSignIn;
import org.telegram.api.requests.TLRequestHelpGetConfig;
import org.telegram.api.requests.TLRequestHelpGetNearestDc;
import org.telegram.api.requests.TLRequestUpdatesGetState;
import org.telegram.api.updates.TLState;
import android.support.v7.app.ActionBarActivity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends ActionBarActivity {
static Context context;
private static AppInfo ai;
private static void createApi() throws IOException {
String res = "No test";
boolean useTest = res.equals("test");
apiState = new MemoryApiState(useTest);
ai=new AppInfo(App_ID, "Sony", "???", "???", "en");
api = new TelegramApi(apiState, ai, new ApiCallback() {
#Override
public void onAuthCancelled(TelegramApi api) {
}
#Override
public void onUpdatesInvalidated(TelegramApi api) {
}
#Override
public void onUpdate(TLAbsUpdates updates) {
Log.d("tlg", "onUpdate(TLAbsUpdates updates)");
}
});
}
private static void login() throws IOException {
//TLNearestDc dcInfo = api.doRpcCallNonAuth(new TLRequestHelpGetNearestDc());
// api.switchToDc(dcInfo.getNearestDc());
//************ Exception raises here ************
TLConfig config = api.doRpcCallNonAuth(new TLRequestHelpGetConfig()); // I have An IOException Here (e=timeout Exception)
apiState.updateSettings(config);
Log.d("tlg","completed.");
String phone = "+9891********"; // I have tested app with the phone without plus too
Log.d("tlg","Sending sms to phone " + phone + "...");
TLSentCode sentCode = null;
try {
api.doRpcCallNonAuth(new TLRequestAuthSendCode(phone, 1, app_id, "__hash__", "en"));
} catch (RpcException e) {
if (e.getErrorCode() == 303) {
int destDC;
if (e.getErrorTag().startsWith("NETWORK_MIGRATE_")) {
destDC = Integer.parseInt(e.getErrorTag().substring("NETWORK_MIGRATE_".length()));
} else if (e.getErrorTag().startsWith("PHONE_MIGRATE_")) {
destDC = Integer.parseInt(e.getErrorTag().substring("PHONE_MIGRATE_".length()));
} else if (e.getErrorTag().startsWith("USER_MIGRATE_")) {
destDC = Integer.parseInt(e.getErrorTag().substring("USER_MIGRATE_".length()));
} else {
throw e;
}
api.switchToDc(destDC);
sentCode = api.doRpcCallNonAuth(new TLRequestAuthSendCode(phone, 0, app_id, "__hash__", "en"));
} else {
throw e;
}
}
Log.d("tlg","Activation code:");
String code = "123";
TLAuthorization auth = api.doRpcCallNonAuth(new TLRequestAuthSignIn(phone, sentCode.getPhoneCodeHash(), code));
apiState.setAuthenticated(apiState.getPrimaryDc(), true);
Log.d("tlg","Activation complete.");
TLState state = api.doRpcCall(new TLRequestUpdatesGetState());
Log.d("tlg","loaded.");
}
static MemoryApiState apiState;
static TelegramApi api;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context=getApplicationContext();
try {
createApi();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
login();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//workLoop();
}
}
I have added telegram-api library (telegram-api-1.1.127-shadow.jar) in my eclipse 'libs' folder. The problem is Timeout Exception in MainActivity.java when I want to call RPC. Where is the problem? What should I do? My OS is windows 8.1 . I am searching for 2 whole days. I have read github codes too. They are very complicated for me. I can not figure out what should I do?
I have added INTERNET and ACCESS_NETWORK_STATE permisions to AndroidManifest.xml. I allways check the network connection when my application runs.
I found the problem in your code:
In MemoryApiState you should put, in the 'connections' map, 'primaryDc' as key and not '1'.

RingtonePreference Theme

Im creating an Android App, totaly in Holo.Light Theme.
All the preferences are light, except for the Ringtonepreference!
I have even tried setting the BGColor and the textColor in the Preferences.xml:
<RingtonePreference
android:icon="#drawable/ic_menu_note"
android:key="ringtone"
android:persistent="true"
android:summary="#string/settings_ringtone2"
android:background="#000000"
android:textColor="#ffffff"
android:title="#string/settings_ringtone" />
Android ignores everything..
Has anybody a clue on how to change the Theme of the RingtonePreference to Holo.Light?
I have found an answer myself, couse as it seems, no App can touch the Ringtonemanager's settings..
So what I did is extending the Listpreference:
package de.Psychologie.socialintelligence;
import java.io.IOException;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.ListPreference;
import android.util.AttributeSet;
public class CustomRingtonepreference extends ListPreference{
private MediaPlayer mMediaPlayer;
CharSequence[] mEntries;
CharSequence[] mEntryValues;
private int mClickedDialogEntryIndex;
private String mValue;
public CustomRingtonepreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomRingtonepreference(Context context) {
super(context);
}
/**
* Sets the value of the key. This should be one of the entries in
* {#link #getEntryValues()}.
*
* #param value The value to set for the key.
*/
public void setValue(String value) {
mValue = value;
persistString(value);
}
/**
* Sets the value to the given index from the entry values.
*
* #param index The index of the value to set.
*/
public void setValueIndex(int index) {
if (mEntryValues != null) {
setValue(mEntryValues[index].toString());
}
}
/**
* Returns the value of the key. This should be one of the entries in
* {#link #getEntryValues()}.
*
* #return The value of the key.
*/
public String getValue() {
return mValue;
}
/**
* Returns the entry corresponding to the current value.
*
* #return The entry corresponding to the current value, or null.
*/
public CharSequence getEntry() {
int index = getValueIndex();
return index >= 0 && mEntries != null ? mEntries[index] : null;
}
public int findIndexOfValue(String value) {
if (value != null && mEntryValues != null) {
for (int i = mEntryValues.length - 1; i >= 0; i--) {
if (mEntryValues[i].equals(value)) {
return i;
}
}
}
return -1;
}
private int getValueIndex() {
return findIndexOfValue(mValue);
}
#Override
protected void onPrepareDialogBuilder(Builder builder) {
super.onPrepareDialogBuilder(builder);
mMediaPlayer = new MediaPlayer();
mEntries = getEntries();
mEntryValues = getEntryValues();
if (mEntries == null || mEntryValues == null) {
throw new IllegalStateException(
"ListPreference requires an entries array and an entryValues array.");
}
mClickedDialogEntryIndex = getValueIndex();
builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mClickedDialogEntryIndex = which;
String value = mEntryValues[which].toString();
try {
playSong(value);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
builder.setPositiveButton("OK", this);
builder.setNegativeButton("Abbrechen", this);
}
private void playSong(String path) throws IllegalArgumentException,
IllegalStateException, IOException {
//Log.d("ringtone", "playSong :: " + path);
mMediaPlayer.reset();
mMediaPlayer.setDataSource(path);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
// mMediaPlayer.setLooping(true);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
setValue(myState.value);
}
private static class SavedState extends BaseSavedState {
String value;
public SavedState(Parcel source) {
super(source);
value = source.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(value);
}
public SavedState(Parcelable superState) {
super(superState);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
#Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult && mClickedDialogEntryIndex >= 0 && mEntryValues != null) {
String value = mEntryValues[mClickedDialogEntryIndex].toString();
if (callChangeListener(value)) {
setValue(value);
}
}
mMediaPlayer.stop();
mMediaPlayer.release();
}
#Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
#Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue);
}
#Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
// No need to save instance state since it's persistent
return superState;
}
final SavedState myState = new SavedState(superState);
myState.value = getValue();
return myState;
}
}
And vor adding the Values I chose the Programmatical way:
//Import All Ringtones
RingtoneManager rm = new RingtoneManager(UserSettingActivity.this);
rm.setType(RingtoneManager.TYPE_ALARM|RingtoneManager.TYPE_RINGTONE );
final Cursor ringtones = rm.getCursor();
List<String> mEntries = new ArrayList<String>();
List<String> mEntryValues = new ArrayList<String>();
for (ringtones.moveToFirst(); !ringtones.isAfterLast(); ringtones.moveToNext()) {
mEntries.add(ringtones.getString(RingtoneManager.TITLE_COLUMN_INDEX));
mEntryValues.add(ringtones.getString(RingtoneManager.URI_COLUMN_INDEX));
}
ringtonepref.setEntryValues(mEntryValues.toArray(new CharSequence[mEntryValues.size()]));
ringtonepref.setEntries(mEntries.toArray(new CharSequence[mEntries.size()]));
And for the initial Initiation with the default Ringtone:
//Sets the default Alarm to the chosen Value
ringtonepref.setValue(RingtoneManager.getActualDefaultRingtoneUri(getBaseContext(), RingtoneManager.TYPE_ALARM).toString());
I hope it helps someone ;)
Well, after spending half the night to get it working, I got a proper solution. I took the advice Trinitrotoluol has written here and merged this with my own functionality. Here is my CustomListPreference (complete, with no step missing)...
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.ListPreference;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.widget.RadioButton;
import java.util.ArrayList;
import java.util.List;
public class CustomListPreference extends ListPreference {
/* Konstante */
private final String TAG = ((Object) this).getClass().getSimpleName();
Context mContext;
LayoutInflater mInflater;
ArrayList<RadioButton> mButtonList;
private MediaPlayer mMediaPlayer;
CharSequence[] mEntries;
CharSequence[] mEntryValues;
private int mActivePositionInList;
private int mTmpActivePositionInList;
private String mValue;
private String mPath;
private String mTmpPath;
public CustomListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mInflater = LayoutInflater.from(context);
mButtonList = new ArrayList<RadioButton>();
Log.d(TAG, "Konstruktor");
// Manager für Benachrichtigungstöne
RingtoneManager ringtoneManager = new RingtoneManager(context);
ringtoneManager.setType(RingtoneManager.TYPE_NOTIFICATION);
final Cursor ringtones = ringtoneManager.getCursor();
List<String> entries = new ArrayList<String>();
List<String> entryValues = new ArrayList<String>();
loadData();
// keine Töne (disabled notification / "warnings")
entries.add("Keine");
entryValues.add("NONE");
for (ringtones.moveToFirst(); !ringtones.isAfterLast(); ringtones.moveToNext()) {
// Anzeige (displays data to screen)
entries.add(ringtones.getString(RingtoneManager.TITLE_COLUMN_INDEX));
// ID beziehen (getting the ID to add it at the end of the path)
int id = ringtones.getInt(ringtones.getColumnIndex(MediaStore.MediaColumns._ID));
// ID ans Ende anfügen (attach ID to the end of the path)
entryValues.add(ringtones.getString(RingtoneManager.URI_COLUMN_INDEX) + "/" + id);
Log.d(TAG, "Tone: " + ringtones.getString(RingtoneManager.URI_COLUMN_INDEX) + "/" + id);
}
setEntryValues(entryValues.toArray(new CharSequence[entryValues.size()]));
setEntries(entries.toArray(new CharSequence[entries.size()]));
}
public CustomListPreference(Context context) {
super(context);
}
public void loadData() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor edit = sp.edit();
if (sp.contains("audio_path")) {
mTmpPath = mPath = sp.getString("audio_path", "NONE");
} else {
edit.putString("audio_path", mPath);
edit.commit();
}
if (sp.contains("audio_id")) {
mTmpActivePositionInList = mActivePositionInList = sp.getInt("audio_id", 0);
} else {
edit.putInt("audio_id", 0);
edit.commit();
}
}
public void setValue(String audioPath, int cursorPosition) {
SharedPreferences sp = getPreferenceManager()
.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor edit = sp.edit();
edit.putString("audio_path", audioPath);
edit.putInt("audio_id", cursorPosition);
edit.commit();
}
public void setOldValues() {
SharedPreferences sp = getPreferenceManager()
.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor edit = sp.edit();
edit.putString("audio_path", mTmpPath);
edit.putInt("audio_id", mTmpActivePositionInList);
edit.commit();
}
public void setValueIndex(int index) {
if (mEntryValues != null) {
setValue(mEntryValues[index].toString());
}
}
public String getValue() {
return mValue;
}
public CharSequence getEntry() {
int index = getValueIndex();
return index >= 0 && mEntries != null ? mEntries[index] : null;
}
public int findIndexOfValue(String value) {
if (value != null && mEntryValues != null) {
for (int i = mEntryValues.length - 1; i >= 0; i--) {
if (mEntryValues[i].equals(value)) {
return i;
}
}
}
return -1;
}
private int getValueIndex() {
return findIndexOfValue(mValue);
}
#Override
protected void onPrepareDialogBuilder(Builder builder) {
super.onPrepareDialogBuilder(builder);
mMediaPlayer = new MediaPlayer();
mEntries = getEntries();
mEntryValues = getEntryValues();
if (mEntries == null || mEntryValues == null) {
throw new IllegalStateException(
"ListPreference requires an entries array and an entryValues array.");
}
builder.setSingleChoiceItems(mEntries, mActivePositionInList,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mActivePositionInList = which;
String path = mEntryValues[which].toString();
try {
RingtoneManager.getRingtone(getContext(), Uri.parse(path)).play();
mPath = path;
} catch (Exception e) {
Log.e(TAG, "Fehler beim Abspielen (Error) : " + e);
}
}
});
builder.setPositiveButton("OK", this);
builder.setNegativeButton("Abbrechen", this);
}
#Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
Log.d(TAG, "pos");
setValue(mPath, mActivePositionInList);
}
if (!positiveResult) {
Log.d(TAG, "neg");
mPath = mTmpPath;
mActivePositionInList = mTmpActivePositionInList;
setOldValues();
}
}
}
to get it right in front on the screen, you can add this snippet to your prefs.xml
<de.yourpackage.right.activities.CustomListPreference
android:dialogTitle="Some text"
android:summary="some text too"
android:title="and more text"
/>
Finally I'm quite happy to get it working now..
PS: if you have questions, feel free to ask.

Starting new activity through Runnable

I check if a string is NULL in a Thread, if its null, the Handler starts
a Runnable which starts a new Activity.
Everything works fine, but, after the new activity is displayed it switches back to the calling Activity and it crashes.
Here is a code snippet.
if(username==null)
{
dialogs.dismiss();
handlers.post(new MyRunable());
}
and Runnable is
public class MyRunable implements Runnable
{
public void run(){
Toast.makeText(ListActivity.this, "Your Connection is too slow",Toast.LENGTH_LONG).show();
startActivity(new Intent(ListActivity.this,Anim.class));
}
}
Here is my Full Source
package com.cram;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Typeface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class BuddyListActivity extends Activity
{
String ss;
private static ProgressDialog dialogs,dialog;
private Thread downloadThreads;
boolean results=false;
Context ctx;
String[]ddd;
ListView lv1;
String [] icons;
BuddyDbAdapter adapter;
NetworkInfo netinfo;
Cursor cursor;
String values;
GetBuddy gb;
BuddyDB db;
String[] username;
String[] firstname;
String[] lastname;
String[] avatar;
String[] id;
File[] iconss;
Handler handlers;
boolean ready=false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.buddy);
db=new BuddyDB(BuddyListActivity.this);
Typeface font = Typeface.createFromAsset(getAssets(),"fonts/Fortheloveofhate.ttf");
TextView btxt = (TextView) findViewById(R.id.textbuddy);
btxt.setTypeface(font);
ctx=getApplicationContext();
lv1=(ListView)findViewById(R.id.list22);
netinfo=null;
adapter=new BuddyDbAdapter(BuddyListActivity.this);
netinfo=checkDataConnection(getApplicationContext());
handlers = new Handler();
adapter.open();
if(netinfo!=null)
{
downloadThreads = (Thread) getLastNonConfigurationInstance();
if (downloadThreads != null && downloadThreads.isAlive()) {
dialog = ProgressDialog.show(this, "Download", "downloading");
}
startdownload();
}
if(netinfo==null)
{
cursor=adapter.showBuddy();
if (cursor==null||cursor.moveToFirst()==false)
{
AlertDialog.Builder buddybox = new AlertDialog.Builder(this);
buddybox.setMessage("You have No Buddies Yet douche!!");
buddybox.setNeutralButton("Okay", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(getBaseContext(),Anim.class));
}
});
buddybox.setCancelable(false);
buddybox.show();
}
else
{
cursor.moveToFirst();
int j=0;
ddd=new String[cursor.getCount()];
icons=new String [cursor.getCount()];
do
{
String firstName = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.BUDDY_FISTNAME));
String lastname = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.BUDDY_LASTNAME));
String Avatar = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.AVATAR));
ddd[j]=firstName+" "+lastname;
Log.d("Test", ddd[j]);
icons[j]=Avatar;
Log.d("Test", icons[j]);
j++;
}while(cursor.moveToNext());
iconss= new File[icons.length];
Log.d("Test",icons.length+"");
for (int q = 0; q < icons.length; q++) {
iconss[q] = new File(Download.ROOT +"/"+ icons[q]+".jpg");
Log.d("Test", iconss[q].getAbsolutePath().toString());
}
//adapter.close();
lv1.setAdapter(new BuddyAdapter(BuddyListActivity.this,R.layout.list1,ddd,iconss));
onDestroy();
}
}
}
private void box() {
// TODO Auto-generated method stub
cursor=adapter.showBuddy();
if (cursor==null||cursor.moveToFirst()==false)
{
dialogs.dismiss();
AlertDialog.Builder buddybox = new AlertDialog.Builder(this);
buddybox.setMessage("You have No Buddies Yet ass!!");
buddybox.setNeutralButton("Okay", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(getBaseContext(),Anim.class));
}
});
buddybox.setCancelable(false);
buddybox.show();
}
}
private NetworkInfo checkDataConnection(Context applicationContext) {
final ConnectivityManager connMgr = (ConnectivityManager)BuddyListActivity.this.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkinfo=null;
final android.net.NetworkInfo wifi =connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile =connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if(wifi.isConnected()||mobile.isConnected())
{networkinfo=connMgr.getActiveNetworkInfo();
return networkinfo;
}
else
{
return null;
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (adapter != null) {
adapter.close();
}
}
#Override
protected void onStop()
{
super.onStop();
finish();
}
private void startdownload() {
dialogs = ProgressDialog.show(BuddyListActivity.this, "Contacting Our Servers", "Geting Your Buddies Avatar");
downloadThreads = new MyThread();
downloadThreads.start();
}
public class MyThread extends Thread {
#Override
public void run() {
try {
new Thread();
GetBuddy tt=new GetBuddy();
String xml=tt.get();
if(xml==null)
{ dialogs.dismiss();
handlers.post(new MyRunable());
ready=false;
//downloadThreads.suspend();
}
final Download cd = new Download();
results = cd.downloadBitmap();
if(results)
{
BuddyParse bp=new BuddyParse();
try {
username=bp.show(xml);
// if(username==null)
// { dialogs.dismiss();
// handlers.post(new MyRunable());
// //downloadThreads.suspend();
// }
firstname=bp.firstname();
lastname=bp.lastname();
avatar=bp.avatar();
id=bp.id();
adapter.deleteAll();
ready=true;
}
catch (ParserConfigurationException e)
{
e.printStackTrace();
}
catch (SAXException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
// Log.d("len", username.length+"");
for(int k=0; k<username.length;k++)
{
adapter.insertBuddy(id[k], username[k], firstname[k], lastname[k], avatar[k]);
Log.d("Test", id[k]+username[k]+firstname[k]+lastname[k]+avatar[k]+"");
}
box();
cursor=adapter.showBuddy();
cursor.moveToFirst();
int i=0;
ddd=new String[cursor.getCount()];
icons=new String [cursor.getCount()];
do
{
String firstName = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.BUDDY_FISTNAME));
String lastname = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.BUDDY_LASTNAME));
String Avatar = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.AVATAR));
ddd[i]=firstName+" "+lastname;
Log.d("Test", ddd[i]);
icons[i]=Avatar;
Log.d("Test",icons[i]);
i++;
}while(cursor.moveToNext());
iconss= new File[avatar.length];
for (int k = 0; k < avatar.length; k++) {
iconss[k] = new File(Download.ROOT+"/"+avatar[k]+".jpg");
Log.d("Test", iconss[k].getAbsolutePath()+"thread");
//Log.d("Test", ddd[k]);
}
if (results&&ready)
{
dialogs.dismiss();
handlers.post(new MyRuns());
}
}
// else
// { dialogs.dismiss();
// handlers.post(new MyRunable());
//
// }
}finally {
}
}
}
public class MyRuns implements Runnable {
public void run() {
ready=true;
lv1.setAdapter(new BuddyAdapter(ctx,R.layout.list1,ddd,iconss));
onDestroy();
}
}
public class MyRunable implements Runnable {
public void run() {
//Toast.makeText(BuddyListActivity.this, "Your Connection is too slow", Toast.LENGTH_LONG).show();
startActivity(new Intent(BuddyListActivity.this,Anim.class));
}
}
}
use main thread to start your thread check runOnUiThread(Runnable action)
Setting RETURN in the try catch block and setting
android:noHistory="true" in Android Manifest for all activities fixed my problem
If you are trying to create an async task in a different thread I would recommend you to use the following class:
private final class MyRunnable extends
AsyncTask<Void, Void, Document> {
protected Document doInBackground(Void... params) {
}
protected void onPostExecute(Document result) {
}
}
You only have to change the parameters.
More info here:
http://developer.android.com/reference/android/os/AsyncTask.html
Finish your current activity when starting another activity from runnable .

Categories

Resources