Delete button stops working sporadically, only on Windows, when using our editor plugin - eclipse-plugin

We are developing a markdown editor plugin for eclipse. My colleagues who are using Windows 10 encounter a bug that causes keys to stop working. The most common key is delete, other times it is ctrl + s.
Here is the code for the editor extension:
public class MarkdownEditor extends AbstractTextEditor {
private Activator activator;
private MarkdownRenderer markdownRenderer;
private IWebBrowser browser;
public MarkdownEditor() throws FileNotFoundException {
setSourceViewerConfiguration(new TextSourceViewerConfiguration());
setDocumentProvider(new TextFileDocumentProvider());
// Activator manages connections to the Workbench
activator = Activator.getDefault();
markdownRenderer = new MarkdownRenderer();
}
private IFile saveMarkdown(IEditorInput editorInput, IDocument document, IProgressMonitor progressMonitor) {
IProject project = getCurrentProject(editorInput);
String mdFileName = editorInput.getName();
String fileName = mdFileName.substring(0, mdFileName.lastIndexOf('.'));
String htmlFileName = fileName + ".html";
IFile file = project.getFile(htmlFileName);
String markdownString = "<!DOCTYPE html>\n" + "<html>" + "<head>\n" + "<meta charset=\"utf-8\">\n" + "<title>"
+ htmlFileName + "</title>\n" + "</head>" + "<body>" + markdownRenderer.render(document.get())
+ "</body>\n" + "</html>";
try {
if (!project.isOpen())
project.open(progressMonitor);
if (file.exists())
file.delete(true, progressMonitor);
if (!file.exists()) {
byte[] bytes = markdownString.getBytes();
InputStream source = new ByteArrayInputStream(bytes);
file.create(source, IResource.NONE, progressMonitor);
}
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return file;
}
private void loadFileInBrowser(IFile file) {
IWorkbench workbench = PlatformUI.getWorkbench();
try {
if (browser == null)
browser = workbench.getBrowserSupport().createBrowser(Activator.PLUGIN_ID);
URL htmlFile = FileLocator.toFileURL(file.getLocationURI().toURL());
browser.openURL(htmlFile);
IWorkbenchPartSite site = this.getSite();
IWorkbenchPart part = site.getPart();
site.getPage().activate(part);
} catch (IOException | PartInitException e) {
e.printStackTrace();
}
}
#Override
public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
super.init(site, editorInput);
IDocumentProvider documentProvider = getDocumentProvider();
IDocument document = documentProvider.getDocument(editorInput);
IFile htmlFile = saveMarkdown(editorInput, document, null);
loadFileInBrowser(htmlFile);
}
#Override
public void doSave(IProgressMonitor progressMonitor) {
IDocumentProvider documentProvider = getDocumentProvider();
if (documentProvider == null)
return;
IEditorInput editorInput = getEditorInput();
IDocument document = documentProvider.getDocument(editorInput);
if (documentProvider.isDeleted(getEditorInput())) {
if (isSaveAsAllowed()) {
/*
* 1GEUSSR: ITPUI:ALL - User should never loose changes made in the editors.
* Changed Behavior to make sure that if called inside a regular save (because
* of deletion of input element) there is a way to report back to the caller.
*/
performSaveAs(progressMonitor);
} else {
}
} else {
// Convert document from string to string array with each instance a single line
// of the document
String[] stringArrayOfDocument = document.get().split("\n");
String[] formattedLines = PipeTableFormat.preprocess(stringArrayOfDocument);
StringBuilder builder = new StringBuilder();
for (String line : formattedLines) {
builder.append(line);
builder.append("\n");
}
String formattedDocument = builder.toString();
// Calculating the position of the cursor
ISelectionProvider selectionProvider = this.getSelectionProvider();
ISelection selection = selectionProvider.getSelection();
int cursorLength = 0;
if (selection instanceof ITextSelection) {
ITextSelection textSelection = (ITextSelection) selection;
cursorLength = textSelection.getOffset(); // etc.
activator.log(Integer.toString(cursorLength));
}
// This sets the cursor on at the start of the file
document.set(formattedDocument);
// Move the cursor
this.setHighlightRange(cursorLength, 0, true);
IFile htmlFile = saveMarkdown(editorInput, document, progressMonitor);
loadFileInBrowser(htmlFile);
performSave(false, progressMonitor);
}
}
private IProject getCurrentProject(IEditorInput editorInput) {
IProject project = editorInput.getAdapter(IProject.class);
if (project == null) {
IResource resource = editorInput.getAdapter(IResource.class);
if (resource != null) {
project = resource.getProject();
}
}
return project;
}
}
Here is the repository: https://github.com/borisv13/GitHub-Flavored-Markdown-Eclipse-Plugin
Any help is accepted

Related

Implement Infinite scroll with ViewModel And Retrofit in recyclerview

Before adding viewmodel & livedata , i successfully implemented infinity scroll with retrofit. But after adding viewmodel & livedata with Retrofit, My can't update recyclerview with new data call or viewmodel observer not update the list.
I simply want to infinite scrolling as my code does before. I add a global variable to reuse next page token. Am i missing anything or any sample to implement infinite recyclerview with viewmodel & retrofit will be awesome.
public static String NEXT_PAGE_URL = null;
I coded like that.
My Activity -> PlaceListActivity
placeRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
LogMe.d(tag, "onScrollStateChanged:: " + "called");
// check scrolling started or not
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
isScrolling = true;
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
LogMe.d(tag, "onScrolled:: " + "called");
super.onScrolled(recyclerView, dx, dy);
currentItem = layoutManager.getChildCount();
totalItems = layoutManager.getItemCount();
scrolledOutItems = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
LogMe.d(tag, "currentItem:: " + currentItem);
LogMe.d(tag, "totalItems:: " + totalItems);
LogMe.d(tag, "scrolledOutItems:: " + scrolledOutItems);
if (isScrolling && (currentItem + scrolledOutItems == totalItems)) {
LogMe.d(tag, "view:: " + "finished");
isScrolling = false;
if (ApplicationData.NEXT_PAGE_URL != null) {
LogMe.d(tag, "place adding:: " + " onScrolled called");
ll_loading_more.setVisibility(View.VISIBLE);
// todo: call web api here
callDataFromLocationAPi(type, ApplicationData.NEXT_PAGE_URL, currentLatLng);
} else {
LogMe.d(tag, "next_page_url:: " + " is null");
}
}
}
});
private void callDataFromLocationAPi(String type, String next_page_url, LatLng latLng) {
if (Connectivity.isConnected(activity)) {
showProgressDialog();
model.getNearestPlaces(type, next_page_url, latLng).
observe(activity, new Observer<List<PlaceDetails>>() {
#Override
public void onChanged(#Nullable List<PlaceDetails> placeDetails) {
ll_loading_more.setVisibility(View.GONE);
LogMe.i(tag, "callDataFromLocationAPi: onChanged called !");
hideProgressDialog();
if (placeDetails != null) {
placeDetailsList = placeDetails;
placeListAdapter.setPlaceList(placeDetails);
}
}
});
} else {
showAlertForInternet(activity);
}
}
In PlaceViewModel
public class PlaceViewModel extends AndroidViewModel {
//this is the data that we will fetch asynchronously
private MutableLiveData<List<PlaceDetails>> placeList;
private PlaceRepository placeRepository;
private String tag = getClass().getName();
public PlaceViewModel(Application application) {
super(application);
placeRepository = new PlaceRepository(application);
}
//we will call this method to get the data
public MutableLiveData<List<PlaceDetails>> getNearestPlaces(String type,
String next_page_token,
LatLng latLng) {
//if the list is null
if (placeList == null) {
placeList = new MutableLiveData<>();
//we will load it asynchronously from server in this method
//loadPlaces(type, next_page_token, latLng);
placeList = placeRepository.getNearestPlacesFromAPI(type, next_page_token, latLng);
}
//finally we will return the list
return placeList;
}
}
In my PlaceRepository.java looks
public class PlaceRepository {
private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
#Override
public void migrate(SupportSQLiteDatabase database) {
// Since we didn't alter the table, there's nothing else to do here.
}
};
private PlaceDatabase placeDatabase;
private CurrentLocation currentLocation = null;
private String tag = getClass().getName();
//this is the data that we will fetch asynchronously
private MutableLiveData<List<PlaceDetails>> placeList;
public PlaceRepository(Context context) {
placeDatabase = PlaceDatabase.getDatabase(context);
//addMigrations(MIGRATION_1_2)
placeList =
new MutableLiveData<>();
}
public MutableLiveData<List<PlaceDetails>> getNearestPlacesFromAPI(String type, final String next_page_token, LatLng latLng) {
List<PlaceDetails> placeDetailsList = new ArrayList<>();
try {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiService.getNearbyPlaces(type,
latLng.latitude + "," +
latLng.longitude, ApplicationData.PROXIMITY_RADIUS,
ApplicationData.PLACE_API_KEY, next_page_token);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
try {
Example example = response.body();
ApplicationData.NEXT_PAGE_URL = example.getNextPageToken();
// next_page_url = example.getNextPageToken();
LogMe.i(tag, "next_page_url:" + ApplicationData.NEXT_PAGE_URL);
if (example.getStatus().equals("OK")) {
LogMe.i("getNearbyPlaces::", " --- " + response.toString() +
response.message() + response.body().toString());
// This loop will go through all the results and add marker on each location.
for (int i = 0; i < example.getResults().size(); i++) {
Double lat = example.getResults().get(i).getGeometry().getLocation().getLat();
Double lng = example.getResults().get(i).getGeometry().getLocation().getLng();
String placeName = example.getResults().get(i).getName();
String vicinity = example.getResults().get(i).getVicinity();
String icon = example.getResults().get(i).getIcon();
String place_id = example.getResults().get(i).getPlaceId();
PlaceDetails placeDetails = new PlaceDetails();
if (example.getResults().get(i).getRating() != null) {
Double rating = example.getResults().get(i).getRating();
placeDetails.setRating(rating);
}
//List<Photo> photoReference = example.getResults().
// get(i).getPhotos();
placeDetails.setName(placeName);
placeDetails.setAddress(vicinity);
placeDetails.setLatitude(lat);
placeDetails.setLongitude(lng);
placeDetails.setIcon(icon);
placeDetails.setPlace_id(place_id);
//placeDetails.setPlace_type(place_type_title);
double value = ApplicationData.
DISTANCE_OF_TWO_LOCATION_IN_KM(latLng.latitude, latLng.longitude, lat, lng);
//new DecimalFormat("##.##").format(value);
placeDetails.setDistance(new DecimalFormat("##.##").format(value));
String ph = "";
if (example.getResults().
get(i).getPhotos() != null) {
try {
List<Photo> photos = example.getResults().
get(i).getPhotos();
//JSONArray array = new JSONArray(example.getResults().
//get(i).getPhotos());
//JSONObject jsonObj = new JSONObject(array.toString());
//ph = jsonObj.getString("photo_reference");
ph = photos.get(0).getPhotoReference();
//LogMe.i(tag, "\n" + ph);
} catch (Exception e) {
e.printStackTrace();
//placeDetails.setPicture_reference(ph);
//PLACE_DETAILS_LIST.add(placeDetails);
//LogMe.i(tag, "#### Exception Occureed ####");
ph = "";
//continue;
}
}
placeDetails.setPicture_reference(ph);
placeDetailsList.add(placeDetails);
placeList.postValue(placeDetailsList);
}
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<Example> call, Throwable t) {
Log.e("onFailure", t.toString());
}
});
} catch (RuntimeException e) {
//hideProgressDialog();
Log.d("onResponse", "RuntimeException is an error");
e.printStackTrace();
} catch (Exception e) {
Log.d("onResponse", "Exception is an error");
}
return placeList;
}
}
I precise code due to question simplicity.
Though you already use android-jetpack, take a look at Paging library. It's specially designed for building infinite lists using RecyclerView.
Based on your source code, I'd say that you need PageKeyedDataSource, here is some example which includes info about how to implement PageKeyedDataSource -
7 steps to implement Paging library in Android
If talking about cons of this approach:
You don't need anymore to observe list scrolling (library doing it for you), you just need to specify your page size in the next way:
PagedList.Config myPagingConfig = new PagedList.Config.Builder()
.setPageSize(50)
.build();
From documentation:
Page size: The number of items in each page.
Your code will be more clear, you'll get rid of your RecyclerView.OnScrollListener
ViewModel code will be shorter, it's will provide only PagedList:
#NonNull
LiveData<PagedList<ReviewSection>> getReviewsLiveData() {
return reviewsLiveData;
}

When merging PDF files using itext the result pdf show 0 bytes in android studio

My code is here; I was selecting PDF files from a SD card or internal phone memory using the showFileChooser() method then from onActivityResult(), the files go to mergePdfFiles(View view) method, and from there the files go to createPdf(String[] srcs).
Here is the complete code of my activity:
//Below is onCreate();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mergedpdf);
adapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, locations);
// public void fileSelected(File file ) {
// locations.add(file.toString());
// adapter.notifyDataSetChanged();
// }
NewText = (TextView)findViewById(R.id.textView);
AdView mAdView = findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
listView = (ListView)findViewById(R.id.list_items);
btn = (ImageView) findViewById(R.id.imageView8);
btnconvert = (ImageView) findViewById(R.id.imageView11);
btnconvert.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// btTag=((Button)v).getTag().toString();
try {
createPdf( locations);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Toast.makeText(Mergedpdf.this, "button clicked", Toast.LENGTH_SHORT).show();
}
});
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// btTag=((Button)v).getTag().toString();
showFileChooser();
NewText.setText("Below Files are Selected");
}
});
}
//this is mergedfiles();
public void mergePdfFiles(View view){
Toast.makeText(Mergedpdf.this, "merge function", Toast.LENGTH_SHORT).show();
try {String[] srcs= new String[locations.size()];
for(int i = 0;i<locations.size();i++) {
srcs[i] = locations.get(i);
}
// String[] srcs = {txt1.getText().toString(), txt2.getText().toString()};
createPdf(srcs);
}catch (Exception e){e.printStackTrace();}
}
//This method create merged pdf file
public void createPdf (String[] srcs) {
try {
// Create document object
File docsFolder = new File(Environment.getExternalStorageDirectory() + "/Merged-PDFFiles");
if (!docsFolder.exists()) {
docsFolder.mkdir();
Log.i(TAG, "Created a new directory for PDF");
}
Date date = new Date();
#SuppressLint("SimpleDateFormat") final String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date);
Document document = new Document();
// pdfCopy = new File(docsFolder.getAbsolutePath(),pdf+"Images.pdf");
// Document document = new Document();
//PdfWriter.getInstance(document, output);
// Create pdf copy object to copy current document to the output mergedresult file
PdfCopy copy = new PdfCopy(document, new FileOutputStream(docsFolder + "/" + timeStamp +"combine.pdf"));
Toast.makeText(Mergedpdf.this, "merged pdf saved", Toast.LENGTH_SHORT).show();
// Open the document
document.open();
PdfReader pr;
int n;
for (int i = 0; i < srcs.length; i++) {
// Create pdf reader object to read each input pdf file
pr = new PdfReader(srcs[i].toString());
// Get the number of pages of the pdf file
n = pr.getNumberOfPages();
for (int page = 1; page <= n; page++) {
// Import all pages from the file to PdfCopy
copy.addPage(copy.getImportedPage(pr, page));
}
}
document.close(); // close the document
} catch (Exception e) {
e.printStackTrace();
}
}
//below is showfilechooser(); method
private void showFileChooser () {
Log.e("AA", "bttag=" + btTag);
String folderPath = Environment.getExternalStorageDirectory() + "/";
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
Uri myUri = Uri.parse(folderPath);
intent.setDataAndType(myUri, "application/pdf");
Intent intentChooser = Intent.createChooser(intent, "Select a file");
startActivityForResult(intentChooser,PICKFILE_RESULT_CODE);
}
//below is onActivityResult(); method
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
if (requestCode == PICKFILE_RESULT_CODE) {
if (resultCode == RESULT_OK) {
String FilePath = data.getData().getPath();
locations.add(FilePath);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.listview,locations);
listView.setAdapter(adapter);
}
}
}
}
//And my declared variables before oncreate().
public com.itextpdf.text.Document Document;
public PdfCopy Copy;
public ByteArrayOutputStream ms;
TextView NewText;
private TextView txt1;
private Button bt1, bt2,bt3;
private Handler handler;
ListView listView;
ArrayList<String> locations = new ArrayList<>();
ArrayAdapter<String> adapter;
ImageView btn, btnconvert, btn3;
private static final String TAG = "PdfCreator";
private final int PICKFILE_RESULT_CODE=10;
private String btTag = "";

API request catches exception NULL response

I am using NYT's developers movie reviews API, and i am at the beginning where i just want to see a response. It appears that i get a NULL response which catches the exception that i will pinpoint on the code. " CharSequence text = "There was an error. Please try again";" to help you find it. Could someone please tell me what causes this problem.
NYT Documentation Link http://developer.nytimes.com/movie_reviews_v2.json#/Documentation/GET/critics/%7Bresource-type%7D.json
public class MainActivity extends AppCompatActivity {
private final String site = "https://api.nytimes.com/svc/movies/v2/reviews/search.json?query=";
public int count;
public int i;
public int j;
public int k;
public int n;
public int comas;
public int ingadded;
public String web2 = "";
public String istos;
public ArrayList<String> mylist = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button next = (Button) findViewById(R.id.button);
final EditText edit_text = (EditText) findViewById(R.id.ing);
final TextView show_ing = (TextView) findViewById(R.id.show_ing);
final Button done = (Button) findViewById(R.id.button3);
final Button refresh = (Button) findViewById(R.id.refresh);
final Button delete = (Button) findViewById(R.id.delete);
final ProgressDialog Dialog = new ProgressDialog(MainActivity.this);
//done move to next activity
done.setOnClickListener(new View.OnClickListener() {
#Override
//CHECK IF TEXT BOX IS EMPTY
public void onClick(View view) {
web2 = edit_text.getText().toString();
//check if there are ingredients added
if (web2 == "") {
Context context = getApplicationContext();
CharSequence text = "Search Bar is Empty!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
Dialog.dismiss();
}
else {
//IF NOT CREATE THE LINK AND SEND IT TO LongOperation
web2 = edit_text.getText().toString();
//create link - MAYBE THE WAY API KEY MUST BE CALLED?
istos = site + web2 + "?api-key=xxxxxxxxxxxx";
Log.v("Showme=", istos);
web2 = "";
// WebServer Request URL
String serverURL = istos;
// Use AsyncTask execute Method To Prevent ANR Problem
new LongOperation().execute(serverURL);
}
}
});
edit_text.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
edit_text.setHint("");
else
edit_text.setHint("Type the title of the movie");
}
});
private class LongOperation extends AsyncTask<String, String, Void> {
// Required initialization
private final HttpClient Client = new DefaultHttpClient();
private String Content;
private String Error = null;
private Integer count;
private int add = 1;
private ProgressDialog Dialog = new ProgressDialog(MainActivity.this);
String data = "";
TextView jsonParsedname = (TextView) findViewById(R.id.jsonParsedname1);
ArrayList<ArrayList<Integer>> numArray = new ArrayList<ArrayList<Integer>>();
int sizeData = 0;
protected void onPreExecute() {
//Start Progress Dialog (Message)
Dialog.setMessage("Finding Movies..");
Dialog.show();
try {
// Set Request parameter
data = "&" + URLEncoder.encode("data", "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Call after onPreExecute method
protected Void doInBackground(String... urls) {
/************ Make Post Call To Web Server ***********/
BufferedReader reader = null;
// Send data
try {
// Defined URL where to send data
URL url = new URL(urls[0]);
// Send POST data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = "";
// Read Server Response
while ((line = reader.readLine()) != null) {
// Append server response in string
sb.append(line + "");
}
// Append Server Response To Content String
Content = sb.toString();
} catch (Exception ex) {
Error = ex.getMessage();
} finally {
try {
reader.close();
} catch (Exception ex) {
}
}
/*****************************************************/
return null;
}
protected void onPostExecute(Void unused) {
// NOTE: You can call UI Element here.
// Close progress dialog
Dialog.dismiss();
if (Error != null) {
Context context = getApplicationContext();
CharSequence text = "There was an error. Please try again";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
Dialog.dismiss();
} else {
JSONObject jsonResponse;
try {
/****** Creates a new JSONObject with name/value mappings from the JSON string. ********/
jsonResponse = new JSONObject(Content);
if (jsonResponse == null) {
jsonParsedname.setText("Wrong Input");
}
/***** Returns the value mapped by name if it exists and is a JSONArray. ***/
/******* Returns null otherwise. *******/
JSONArray jsonMainNode = jsonResponse.optJSONArray("results");

Osmdroid - from offline folder

I am using OSMdroid to display both online and offline data in my app. The offline data are stored in a .zip file with the required structure.
Is it possible to have these offline tiles stored in a directory (extracted .zip file with the same structure)?
Could somebody please tell me how could I achive this?
Thank you.
I am sorry. I should try more before asking. But I am leaving this question here, somebody could find it useful.
Solution:
New MapTileFileProvider. I called it MapTileFileFolderProvider, it is a lightly modified MapTileFileArchiveProvider. It is using folders instead of archives. The modifications are not perfect, it is a "hot solution" that needs someone more experienced in Java/Android to make it properly.
Benefits from loading Tiles from folders:
Faster loading of tiles (I know, I won't recognize the difference).
Easier updates focused only on changed tiles not whole map plans.
Application can download tiles when is in "online mode" and then use the downloaded Tiles offline.
MapTileFileFolderProvider - only modifications
public class MapTileFileArchiveProvider extends MapTileFileStorageProviderBase
public class MapTileFileFolderProvider extends MapTileFileStorageProviderBase {
private final boolean mSpecificFoldersProvided;
private final ArrayList<String> mFolders = new ArrayList<String>();
private final AtomicReference<ITileSource> mTileSource = new AtomicReference<ITileSource>();
...
}
public MapTileFileArchiveProvider(...)
public MapTileFileFolderProvider(final IRegisterReceiver pRegisterReceiver,
final ITileSource pTileSource,
final String[] pFolders) {
super(pRegisterReceiver, NUMBER_OF_TILE_FILESYSTEM_THREADS,
TILE_FILESYSTEM_MAXIMUM_QUEUE_SIZE);
setTileSource(pTileSource);
if (pFolders == null) {
mSpecificFoldersProvided = false;
findFolders();
} else {
mSpecificFoldersProvided = true;
for (int i = pFolders.length - 1; i >= 0; i--) {
mFolders.add(pFolders[i]);
}
}
}
findArchiveFiles()
private void findFolders() {
mFolders.clear();
if (!getSdCardAvailable()) {
return;
}
String baseDirPath = Environment.getExternalStorageDirectory().toString()+"/ctu_navigator"; // TODO get from Config
File dir=new File(baseDirPath);
final File[] files = dir.listFiles();
if (files != null) {
String fileName;
for (File file : files) {
if (file.isDirectory()) {
fileName = baseDirPath + '/' + file.getName();
mFolders.add(fileName);
Utils.log(PlanTileProviderFactory.class, "Added map source: " + fileName);
}
}
}
}
#Override
protected String getName() {
return "Folders Provider";
}
#Override
protected String getThreadGroupName() {
return "folder";
}
protected class TileLoader extends MapTileModuleProviderBase.TileLoader {
#Override
public Drawable loadTile(final MapTileRequestState pState) {
ITileSource tileSource = mTileSource.get();
if (tileSource == null) {
return null;
}
final MapTile pTile = pState.getMapTile();
// if there's no sdcard then don't do anything
if (!getSdCardAvailable()) {
Utils.log("No sdcard - do nothing for tile: " + pTile);
return null;
}
InputStream inputStream = null;
try {
inputStream = getInputStream(pTile, tileSource);
if (inputStream != null) {
Utils.log("Use tile from folder: " + pTile);
final Drawable drawable = tileSource.getDrawable(inputStream);
return drawable;
}
} catch (final Throwable e) {
Utils.log("Error loading tile");
Utils.logError(getClass(), (Exception) e);
} finally {
if (inputStream != null) {
StreamUtils.closeStream(inputStream);
}
}
return null;
}
private synchronized InputStream getInputStream(final MapTile pTile, final ITileSource tileSource) {
for (final String folder : mFolders) {
final String path = folder + '/' + tileSource.getTileRelativeFilenameString(pTile);
File mapTileFile = new File(path);
InputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(mapTileFile));
} catch (IOException e) {
//Utils.log("Tile " + pTile + " not found in " + path);
}
if (in != null) {
Utils.log("Found tile " + pTile + " in " + path);
return in;
}
}
Utils.log("Tile " + pTile + " not found.");
return null;
}
}
Well, as far as I understand what you are trying to get... this is more or less what the standard XYTileSource is already doing.
So if you simply use a ready-to-use tile source like this one:
map.setTileSource(TileSourceFactory.MAPNIK);
you will see downloaded tiles files stored in /sdcard/osmdroid/tiles/Mapnik/
The main difference is that it adds a ".tile" extension at the end of each tile file (probably to prevent tools like Android gallery to index all those images).
If you have a ZIP file with tiles ready to use, you could extract them in this directory, and add .tile extension to each tile (355.png => 355.png.tile)
And TileSourceFactory.MAPNIK will be able to use them.

How to send file with file name by use wifidirect?

I use wifidirect to send file,but I can't get the file name(include .jpg or .mp3),and sent it,it always null.
i'm using wifidirect demo provided Android Developers
I use
File f = new File(uri.getPath());
fileName = f.getName();
and
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ "Wifidirect" + "/" + fileName);
but fileName is alwas null
public class DeviceDetailFragment extends Fragment implements ConnectionInfoListener {
protected static final int CHOOSE_FILE_RESULT_CODE = 20;
private View mContentView = null;
private WifiP2pDevice device;
private WifiP2pInfo info;
//private static WiFiDirectBundle bundle = new WiFiDirectBundle();
ProgressDialog progressDialog = null;
private static String fileName;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContentView = inflater.inflate(R.layout.device_detail, null);
mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
config.groupOwnerIntent = 15;
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel",
"Connecting to :" + device.deviceAddress, true, true
// new DialogInterface.OnCancelListener() {
//
// #Override
// public void onCancel(DialogInterface dialog) {
// ((DeviceActionListener) getActivity()).cancelDisconnect();
// }
// }
);
((DeviceActionListener) getActivity()).connect(config);
}
});
mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
((DeviceActionListener) getActivity()).disconnect();
}
});
mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// Allow user to pick an image from Gallery or other
// registered apps
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
}
});
return mContentView;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// User has picked an image. Transfer it to group owner i.e peer using
// FileTransferService.
Uri uri = data.getData();
File f = new File(uri.getPath());
fileName = f.getName();
TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
statusText.setText("Sending: " + uri);
Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
Intent serviceIntent = new Intent(getActivity(), FileTransferService.class);
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
info.groupOwnerAddress.getHostAddress());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
getActivity().startService(serviceIntent);
}
#Override
public void onConnectionInfoAvailable(final WifiP2pInfo info) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
this.info = info;
this.getView().setVisibility(View.VISIBLE);
// The owner IP is now known.
TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
view.setText(getResources().getString(R.string.group_owner_text)
+ ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
: getResources().getString(R.string.no)));
// InetAddress from WifiP2pInfo struct.
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
// After the group negotiation, we assign the group owner as the file
// server. The file server is single threaded, single connection server
// socket.
if (info.groupFormed && info.isGroupOwner) {
new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
.execute();
} else if (info.groupFormed) {
// The other device acts as the client. In this case, we enable the
// get file button.
mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
((TextView) mContentView.findViewById(R.id.status_text)).setText(getResources()
.getString(R.string.client_text));
}
// hide the connect button
mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
}
/**
* Updates the UI with device data
*
* #param device the device to be displayed
*/
public void showDetails(WifiP2pDevice device) {
this.device = device;
this.getView().setVisibility(View.VISIBLE);
TextView view = (TextView) mContentView.findViewById(R.id.device_address);
view.setText(device.deviceAddress);
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText(device.toString());
}
/**
* Clears the UI fields after a disconnect or direct mode disable operation.
*/
public void resetViews() {
mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
TextView view = (TextView) mContentView.findViewById(R.id.device_address);
view.setText(R.string.empty);
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText(R.string.empty);
view = (TextView) mContentView.findViewById(R.id.group_owner);
view.setText(R.string.empty);
view = (TextView) mContentView.findViewById(R.id.status_text);
view.setText(R.string.empty);
mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE);
this.getView().setVisibility(View.GONE);
}
/**
* A simple server socket that accepts connection and writes some data on
* the stream.
*/
public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
private Context context;
private TextView statusText;
//String FileName = "bundle.fileName";
/**
* #param context
* #param statusText
*/
public FileServerAsyncTask(Context context, View statusText) {
this.context = context;
this.statusText = (TextView) statusText;
}
#Override
protected String doInBackground(Void... params) {
try {
ServerSocket serverSocket = new ServerSocket(8988);
Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
Socket client = serverSocket.accept();
Log.d(WiFiDirectActivity.TAG, "Server: connection done");
/*final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ "Wifidirect" + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");*/
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ "Wifidirect" + "/" + fileName);
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
return f.getAbsolutePath();
} catch (IOException e) {
Log.e(WiFiDirectActivity.TAG, e.getMessage());
return null;
}
}
/*
* (non-Javadoc)
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(String result) {
if (result != null) {
statusText.setText("File copied - " + result);
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + result), "image/*");
context.startActivity(intent);
}
}
/*
* (non-Javadoc)
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
statusText.setText("Opening a server socket");
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
Log.d(WiFiDirectActivity.TAG, e.toString());
return false;
}
return true;
}
}
File f = new File(uri.getPath());
fileName = f.getName();
This part of code in your app will get executed - if device acts as client
and
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ "Wifidirect" + "/" + fileName);
this part of code in your app will get executed - if device acts as server (in this case GO) but fileName is always null
Since filename is initialized to "null" , on the server device this will be null.
FileServerAsyncTask is created only on GO( server ) as per the code.
In android sample code file transfer is working only from client to server. In this code user can do file sharing in both directions i.e client to server as well as server to client.
You can see this link.
How can I transfer files between Android devices using Wi-Fi Direct?