问:
Google map API setIcon is functioning wierdly
First marker.setIcon never worked for me.
I checked in browser console, this is what it shows:

So I tried using markerObject.icon = "/Content/img/icon_critical.svg"
(Actually it should be "/Content/img/icon_selected.svg", I was trying to check if its the image that it can't access)

And that is giving me a wierd output. No matter which marker i click, only a particular marker icon changes all the time.And everything else just remains the same. Plus this change doesn't occur every time. Its like sometimes its happening, sometimes it just doesn't do anything

The code i used to add the handler is

```<code>var cautionIcon = "/Content/img/icon_caution.svg";
var criticalIcon = "/Content/img/icon_critical.svg";
var selectIcon = "/Content/img/icon_selected.svg";

var options = {
        zoom: 8,
        center: new google.maps.LatLng(-34, 151),
        mapTypeId: google.maps.MapTypeId.ROADMAP, //aerial //canvasDark //grayscale
        zoomControl: true
    };

self.map = new google.maps.Map(document.getElementById('deviceMap'), options);

var setDeviceLocationData = function setDeviceLocationData(minLatitude, minLongitude, maxLatitude, maxLongitude, deviceLocations) {
    var i;
    var loc;
    var mapOptions;
    var pin;
    var pinOptions;

    if (!self.map) {
        return;
    }

    if (!boundsSet) {
        boundsSet = true;
        self.map.fitBounds(
            new google.maps.LatLngBounds(
                new google.maps.LatLng(maxLatitude, minLongitude),
                new google.maps.LatLng(minLatitude, maxLongitude)
            )
        );
    }

    if (deviceLocations) {
        for (i = 0; i < deviceLocations.length; ++i) {
            loc = new google.maps.LatLng(deviceLocations[i].latitude, deviceLocations[i].longitude);

            pinOptions = {
                position: loc,
                map: self.map,
                zIndex: deviceLocations[i].status
            };

            switch (deviceLocations[i].status) {
                case 1:
                    pinOptions.icon = cautionIcon;
                    break;

                case 2:
                    pinOptions.icon = criticalIcon;
                    break;
            }

            pin = new google.maps.Marker(pinOptions);
            google.maps.event.addListener(pin, 'click', function () {
                pin.setIcon(selectIcon); // this never works
                pin.icon = resources.selectedIcon;  // this works sometimes with that wierd output i mentioned above.
            });
        }
    }
}
</code>```

This method setDeviceLocationData gets called every 5 secs in the success callback of an ajax method which in turn calls a web api controller that returns deviceLocations.

deviceLocations looks something like this:

u can use deviceLocations like below:

```<code>var deviceLocations = [
{
   "latitude": "33.5346",
   "longitude": "88.579989",
   "status":"1"
},
{
   "latitude": "33.53566",
   "longitude": "88.173395",
   "status":"2"
},
{
   "latitude": "33.6346",
   "longitude": "88.570989",
   "status":"1"
},
{
   "latitude": "33.1346",
   "longitude": "88.679889",
   "status":"1"
},];
</code>```

PS: Everything else works except the marker color change.
I tried viewing an infobox but worked just fine.

Could it be because I might have an API key issue? Like I have an old version api key. Or is it that the map wouldn't have loaded at all if it was something like that.

And in my Google Developers Console I have only 1 api key, and that shows something like this. Incase this helps.

答:
```<code>pin.setIcon(selectIcon); // this never works
</code>```

You say "this never works", but it does work, albeit on the last marker.  That is a sign of a common problem in markers created in loops, which can be fixed with function closure or using the this inside the click listener (instead of pin which is left referencing the last marker).

```<code>var pin = new google.maps.Marker(pinOptions);
google.maps.event.addListener(pin, 'click', function () {
    this.setIcon(selectIcon); // this never works
});
</code>```

updated fiddle

code snippet:

var geocoder;
var map;

var deviceLocations = [{
  "latitude": "33.5346",
  "longitude": "88.579989",
  "status": "1"
}, {
  "latitude": "33.53566",
  "longitude": "88.173395",
  "status": "2"
}, {
  "latitude": "33.6346",
  "longitude": "88.570989",
  "status": "1"
}, {
  "latitude": "33.1346",
  "longitude": "88.679889",
  "status": "1"
}];

function initialize() {
  var loc;
  var pinOptions;
  var pin;
  var map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(33, 88),
      zoom: 8,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

  if (deviceLocations) {
    for (i = 0; i < deviceLocations.length; ++i) {
      loc = new google.maps.LatLng(deviceLocations[i].latitude, deviceLocations[i].longitude);

      pinOptions = {
        position: loc,
        map: map,
        // zIndex: deviceLocations[i].status // InvalidValueError: setZIndex: not a number
      };

      switch (deviceLocations[i].status) {
        case 1:
          pinOptions.icon = cautionIcon;
          break;

        case 2:
          pinOptions.icon = criticalIcon;
          break;
      }

      var pin = new google.maps.Marker(pinOptions);
      google.maps.event.addListener(pin, 'click', function() {
        this.setIcon(selectIcon); // this never works
      });
    }
  }
}
google.maps.event.addDomListener(window, "load", initialize);
var cautionIcon = "http://maps.google.com/mapfiles/ms/micons/orange.png";
var criticalIcon = "http://maps.google.com/mapfiles/ms/micons/yellow.png";
var selectIcon = "http://maps.google.com/mapfiles/ms/micons/blue.png";```
<pre class="snippet-code-css lang-css prettyprint-override"><code>html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}</code>```

```

Body:
First marker.setIcon never worked for me.
I checked in browser console, this is what it shows:

So I tried using markerObject.icon = "/Content/img/icon_critical.svg"
(Actually it should be "/Content/img/icon_selected.svg", I was trying to check if its the image that it can't access)

And that is giving me a wierd output. No matter which marker i click, only a particular marker icon changes all the time.And everything else just remains the same. Plus this change doesn't occur every time. Its like sometimes its happening, sometimes it just doesn't do anything

The code i used to add the handler is

var cautionIcon = "/Content/img/icon_caution.svg";
var criticalIcon = "/Content/img/icon_critical.svg";
var selectIcon = "/Content/img/icon_selected.svg";

var options = {
        zoom: 8,
        center: new google.maps.LatLng(-34, 151),
        mapTypeId: google.maps.MapTypeId.ROADMAP, //aerial //canvasDark //grayscale
        zoomControl: true
    };

self.map = new google.maps.Map(document.getElementById('deviceMap'), options);

var setDeviceLocationData = function setDeviceLocationData(minLatitude, minLongitude, maxLatitude, maxLongitude, deviceLocations) {
    var i;
    var loc;
    var mapOptions;
    var pin;
    var pinOptions;

    if (!self.map) {
        return;
    }

    if (!boundsSet) {
        boundsSet = true;
        self.map.fitBounds(
            new google.maps.LatLngBounds(
                new google.maps.LatLng(maxLatitude, minLongitude),
                new google.maps.LatLng(minLatitude, maxLongitude)
            )
        );
    }

    if (deviceLocations) {
        for (i = 0; i < deviceLocations.length; ++i) {
            loc = new google.maps.LatLng(deviceLocations[i].latitude, deviceLocations[i].longitude);

            pinOptions = {
                position: loc,
                map: self.map,
                zIndex: deviceLocations[i].status
            };

            switch (deviceLocations[i].status) {
                case 1:
                    pinOptions.icon = cautionIcon;
                    break;

                case 2:
                    pinOptions.icon = criticalIcon;
                    break;
            }

            pin = new google.maps.Marker(pinOptions);
            google.maps.event.addListener(pin, 'click', function () {
                pin.setIcon(selectIcon); // this never works
                pin.icon = resources.selectedIcon;  // this works sometimes with that wierd output i mentioned above.
            });
        }
    }
}

This method setDeviceLocationData gets called every 5 secs in the success callback of an ajax method which in turn calls a web api controller that returns deviceLocations.

deviceLocations looks something like this:

u can use deviceLocations like below:

var deviceLocations = [
{
   "latitude": "33.5346",
   "longitude": "88.579989",
   "status":"1"
},
{
   "latitude": "33.53566",
   "longitude": "88.173395",
   "status":"2"
},
{
   "latitude": "33.6346",
   "longitude": "88.570989",
   "status":"1"
},
{
   "latitude": "33.1346",
   "longitude": "88.679889",
   "status":"1"
},];

PS: Everything else works except the marker color change.
I tried viewing an infobox but worked just fine.

Could it be because I might have an API key issue? Like I have an old version api key. Or is it that the map wouldn't have loaded at all if it was something like that.

And in my Google Developers Console I have only 1 api key, and that shows something like this. Incase this helps.

Body:
pin.setIcon(selectIcon); // this never works

You say "this never works", but it does work, albeit on the last marker.  That is a sign of a common problem in markers created in loops, which can be fixed with function closure or using the this inside the click listener (instead of pin which is left referencing the last marker).

var pin = new google.maps.Marker(pinOptions);
google.maps.event.addListener(pin, 'click', function () {
    this.setIcon(selectIcon); // this never works
});

updated fiddle

code snippet:

var geocoder;
var map;

var deviceLocations = [{
  "latitude": "33.5346",
  "longitude": "88.579989",
  "status": "1"
}, {
  "latitude": "33.53566",
  "longitude": "88.173395",
  "status": "2"
}, {
  "latitude": "33.6346",
  "longitude": "88.570989",
  "status": "1"
}, {
  "latitude": "33.1346",
  "longitude": "88.679889",
  "status": "1"
}];

function initialize() {
  var loc;
  var pinOptions;
  var pin;
  var map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(33, 88),
      zoom: 8,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

  if (deviceLocations) {
    for (i = 0; i < deviceLocations.length; ++i) {
      loc = new google.maps.LatLng(deviceLocations[i].latitude, deviceLocations[i].longitude);

      pinOptions = {
        position: loc,
        map: map,
        // zIndex: deviceLocations[i].status // InvalidValueError: setZIndex: not a number
      };

      switch (deviceLocations[i].status) {
        case 1:
          pinOptions.icon = cautionIcon;
          break;

        case 2:
          pinOptions.icon = criticalIcon;
          break;
      }

      var pin = new google.maps.Marker(pinOptions);
      google.maps.event.addListener(pin, 'click', function() {
        this.setIcon(selectIcon); // this never works
      });
    }
  }
}
google.maps.event.addDomListener(window, "load", initialize);
var cautionIcon = "http://maps.google.com/mapfiles/ms/micons/orange.png";
var criticalIcon = "http://maps.google.com/mapfiles/ms/micons/yellow.png";
var selectIcon = "http://maps.google.com/mapfiles/ms/micons/blue.png";

html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}

<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>


来源: stackexchange

问:
How to get the name of enumeration value in Swift?
If I have an enumeration with raw Integer values:

```<code>enum City: Int {
  case Melbourne = 1, Chelyabinsk, Bursa
}

let city = City.Melbourne
</code>```

How can I convert a city value to a string Melbourne? Is this kind of a type name introspection available in the language?

Something like (this code will not work):

```<code>println("Your city is \(city.magicFunction)")
> Your city is Melbourne
</code>```

答:
For Swift:

```<code>extension UIDeviceBatteryState: CustomStringConvertible {

    public var description: String {
        switch self {
        case .unknown:
            return "unknown"
        case .unplugged:
            return "unplugged"
        case .charging:
            return "charging"
        case .full:
            return "full"
        }
    }

}
</code>```

if your variable "batteryState" then call:

```<code>self.batteryState.description
</code>```

ContentLicense: CC BY-SA 3.0

Body:
If I have an enumeration with raw Integer values:

enum City: Int {
  case Melbourne = 1, Chelyabinsk, Bursa
}

let city = City.Melbourne

How can I convert a city value to a string Melbourne? Is this kind of a type name introspection available in the language?

Something like (this code will not work):

println("Your city is \(city.magicFunction)")
> Your city is Melbourne

Body:
For Swift:

extension UIDeviceBatteryState: CustomStringConvertible {

    public var description: String {
        switch self {
        case .unknown:
            return "unknown"
        case .unplugged:
            return "unplugged"
        case .charging:
            return "charging"
        case .full:
            return "full"
        }
    }

}

if your variable "batteryState" then call:

self.batteryState.description

ContentLicense: CC BY-SA 4.0


问:
Re-declaring variable inside for loop in C
I have compiled following program using  gcc prog.c -Wall -Wextra -std=gnu11 -pedantic command on GCC compiler. I wondered, it is working fine without any warnings or errors.

```<code>#include <stdio.h>

int main(void)
{
    for (int i = 0; i == 0;  i++)
    {
        printf("%d\n", i);
        long int i = 1; // Why doesn't redeclaration error?
        printf("%ld\n", i);
    }
}
</code>```

Why compiler doesn't generate redeclaration variable i error?

答:
For further verification i checked this code in visual studio 2008 for the prog.c file. I found that the compiler does give error in the line for (int i = 0; i == 0;  i++) . The compiler expects declaration of i to be in the beginning of the program itself. This behavior is correct for a C file. If the declaration is moved to the beginning of the program then there are no errors as expected. All scope related issues are solved.

If i try this code as prog.cpp file, then the compiler does give an error for redeclaration. This is also an expected behavior.

So i conclude this has to do with the gcc compiler, does any flag/parameters that is used for compiling/building the exe results in this behavior for the gcc compiler.

Can rsp post the make file details for further verification?

Body:
I have compiled following program using  gcc prog.c -Wall -Wextra -std=gnu11 -pedantic command on GCC compiler. I wondered, it is working fine without any warnings or errors.

#include <stdio.h>

int main(void)
{
    for (int i = 0; i == 0;  i++)
    {
        printf("%d\n", i);
        long int i = 1; // Why doesn't redeclaration error?
        printf("%ld\n", i);
    }
}

Why compiler doesn't generate redeclaration variable i error?


问:
Is it possible to rewrite strings in unknown json structure?
I have a requirement to parse arbitrary json, encode/rewrite any string key or value longer than 85 characters(think of a kind of short URL service) and marshal it back to raw json.
 e.g. a document like this {"Name": "Ed", "Text": "long characters....85 chars"} should become something like this {"Name": "Ed", "Text": "short://ID=3403"}. This example is simple but I have to deal with complex structures with nested objects and arrays and basically unknown  structures.

My question is: Is it possible to do this using a known library or even the standard encoding/json package?
 What I actually need is the equivalent of an implementation of Marshaler interface on type  string but we know that's not possible so I'm wondering what other options I have (beside forking the standard encoding/json package)

答:
If the requirement is to replace all strings longer than 85 characters with a new shortened version in a JSON and if you can assume the JSON is a valid JSON (i.e. if you're not required to give a diagnostic in case of invalid input) then you can just use a single regexp substitution.

A quoted string in a valid JSON can be matched with

```<code>/"([^\\"]|\\.)*"/
</code>```

therefore you could just replace all instances of this pattern with the possibly shortened version.

Body:
If the requirement is to replace all strings longer than 85 characters with a new shortened version in a JSON and if you can assume the JSON is a valid JSON (i.e. if you're not required to give a diagnostic in case of invalid input) then you can just use a single regexp substitution.

A quoted string in a valid JSON can be matched with

/"([^\\"]|\\.)*"/

therefore you could just replace all instances of this pattern with the possibly shortened version.


问:
Can't show the color in interactive highchart choropleth map
I'm trying to use HTML selection box and highmaps in highcharts library to highlight the different part my of map when I select. But the color doesn't show up, please check my code in jsfiddle, thanks.

CODE↓↓↓

HTML

```<code><script src="https://code.highcharts.com/maps/highmaps.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/tw/tw-all.js"></script>

<div align="center" style="font-size:110%">
  Product:
  <select name='location' onchange="updateChart(this.value)" style="font-size:110%">
    <option value="" selected value="">Select</option>
    <option value="orange">Orange</option>
    <option value="cabbage">Cabbage</option>
    <option value="peanut">Peanut</option>
  </select>
</div>
<br>
<div id="container" style="height: 500px; min-width: 310px; max-width: 600px; margin: 0 auto"></div>
</code>```

javascript

```<code>var data_orange = [
  ['tw-pt', 1],
  ['tw-ml', 1],
  ['tw-il', 1]
];
var data_cabbage = [
  ['tw-hl', 1],
  ['tw-nt', 1]
];
var data_peanut = [
  ['tw-tw', 1],
  ['tw-tp', 1]
];
var data_series = [
{name: 'orange',
data: data_orange},
{name: 'cabbage',
data: data_cabbage},
{name: 'peanut',
data: data_peanut},
];

// Instanciate the map
Highcharts.mapChart('container', {
  chart: {
    borderWidth: 1
  },

  title: {
    text: 'December product map'
  },
  subtitle: {
    text: 'Data Source: AFA Taiwan'
  },

  legend: {
    enabled: false
  },
  mapNavigation: {
    enabled: true,
    buttonOptions: {
      verticalAlign: 'bottom'
    }
  },
  series: [{
    name: 'Country',
    mapData: Highcharts.maps['countries/tw/tw-all'],
    data: [
      data_series
    ],
    color: '#ff0066',
    dataLabels: {
      enabled: true,
      color: '#FFFFFF',
      formatter: function() {
        if (this.point.value) {
          return this.point.name;
        }
      }
    },
    tooltip: {
      headerFormat: '',
      pointFormat: '{point.name}'
    }
  }],
});

window.updateChart = function(selection) {
  if (selection == "") {
    Highcharts.mapChart.series = [data_series];
  } else if (selection == "orange") {
    //console.log(data_series[0].data)
    Highcharts.mapChart.series.data = data_series[0].data;
  } else if (selection == "cabbage") {
    Highcharts.mapChart.series.data = data_series[1].data;
  } else if (selection == "peanut") {
    Highcharts.mapChart.series.data = data_series[2].data;
  }
  console.log(Highcharts.mapChart.series.data)
  //Highcharts.chart('container', chartOptions);
}

//start rendering----------------------------------------------
updateChart("");
</code>```

答:
You can update Code as

var data_orange = [
  ['tw-pt', 1],
  ['tw-ml', 1],
  ['tw-il', 1]
];
var data_cabbage = [
  ['tw-hl', 1],
  ['tw-nt', 1]
];
var data_peanut = [
  ['tw-tw', 1],
  ['tw-tp', 1]
];

var all_data = [
  ['tw-pt', 1],
  ['tw-ml', 1],
  ['tw-il', 1],
  ['tw-hl', 1],
  ['tw-nt', 1],
  ['tw-tw', 1],
  ['tw-tp', 1],
]
var data_series = [{
  name: 'orange',
  data: data_orange
}, {
  name: 'cabbage',
  data: data_cabbage
}, {
  name: 'peanut',
  data: data_peanut
}, {
  name: 'All',
  data: all_data,
}];
var chart;

function createChart(chartData) {
  // Instanciate the map
  chart = new Highcharts.mapChart('container', {
    chart: {
      borderWidth: 1
    },

    title: {
      text: 'December product map'
    },
    subtitle: {
      text: 'https://stackoverflow.com/questions/47646879/cant-show-the-color-in-interactive-highchart-choropleth-map'
    },

    legend: {
      enabled: false
    },
    mapNavigation: {
      enabled: true,
      buttonOptions: {
        verticalAlign: 'bottom'
      }
    },
    series: [{
      name: 'Country',
      mapData: Highcharts.maps['countries/tw/tw-all'],
      data: chartData,
      dataLabels: {
        enabled: true,
        color: '#FFFFFF',
        formatter: function() {
          if (this.point.value) {
            return this.point.name;
          }
        }
      },
      tooltip: {
        headerFormat: '',
        pointFormat: '{point.name}'
      }
    }]
  });

}

window.updateChart = function(selection) {
  if (selection == "") {
    createChart(data_series[3].data);
  } else if (selection == "orange") {
    createChart(data_series[0].data)

  } else if (selection == "cabbage") {
    createChart(data_series[1].data)
  } else if (selection == "peanut") {
    createChart(data_series[2].data)
  }

}

//start rendering----------------------------------------------
updateChart("");```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://code.highcharts.com/maps/highmaps.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/tw/tw-all.js"></script>

<div align="center" style="font-size:110%">
  Product:
  <select name='location' onchange="updateChart(this.value)" style="font-size:110%">
    <option value="" selected value="">Select</option>
    <option value="orange">Orange</option>
    <option value="cabbage">Cabbage</option>
    <option value="peanut">Peanut</option>
  </select>
</div>
<br>
<div id="container" style="height: 500px; min-width: 310px; max-width: 600px; margin: 0 auto"></div></code>```

Body:
I'm trying to use HTML selection box and highmaps in highcharts library to highlight the different part my of map when I select. But the color doesn't show up, please check my code in jsfiddle, thanks.

CODE↓↓↓

HTML

  Product:
  <select name='location' onchange="updateChart(this.value)" style="font-size:110%">
    <option value="" selected value="">Select</option>
    <option value="orange">Orange</option>
    <option value="cabbage">Cabbage</option>
    <option value="peanut">Peanut</option>
  </select>

javascript

var data_orange = [
  ['tw-pt', 1],
  ['tw-ml', 1],
  ['tw-il', 1]
];
var data_cabbage = [
  ['tw-hl', 1],
  ['tw-nt', 1]
];
var data_peanut = [
  ['tw-tw', 1],
  ['tw-tp', 1]
];
var data_series = [
{name: 'orange',
data: data_orange},
{name: 'cabbage',
data: data_cabbage},
{name: 'peanut',
data: data_peanut},
];

// Instanciate the map
Highcharts.mapChart('container', {
  chart: {
    borderWidth: 1
  },

  title: {
    text: 'December product map'
  },
  subtitle: {
    text: 'Data Source: AFA Taiwan'
  },

  legend: {
    enabled: false
  },
  mapNavigation: {
    enabled: true,
    buttonOptions: {
      verticalAlign: 'bottom'
    }
  },
  series: [{
    name: 'Country',
    mapData: Highcharts.maps['countries/tw/tw-all'],
    data: [
      data_series
    ],
    color: '#ff0066',
    dataLabels: {
      enabled: true,
      color: '#FFFFFF',
      formatter: function() {
        if (this.point.value) {
          return this.point.name;
        }
      }
    },
    tooltip: {
      headerFormat: '',
      pointFormat: '{point.name}'
    }
  }],
});

window.updateChart = function(selection) {
  if (selection == "") {
    Highcharts.mapChart.series = [data_series];
  } else if (selection == "orange") {
    //console.log(data_series[0].data)
    Highcharts.mapChart.series.data = data_series[0].data;
  } else if (selection == "cabbage") {
    Highcharts.mapChart.series.data = data_series[1].data;
  } else if (selection == "peanut") {
    Highcharts.mapChart.series.data = data_series[2].data;
  }
  console.log(Highcharts.mapChart.series.data)
  //Highcharts.chart('container', chartOptions);
}

//start rendering----------------------------------------------
updateChart("");

Body:
You can update Code as

var data_orange = [
  ['tw-pt', 1],
  ['tw-ml', 1],
  ['tw-il', 1]
];
var data_cabbage = [
  ['tw-hl', 1],
  ['tw-nt', 1]
];
var data_peanut = [
  ['tw-tw', 1],
  ['tw-tp', 1]
];

var all_data = [
  ['tw-pt', 1],
  ['tw-ml', 1],
  ['tw-il', 1],
  ['tw-hl', 1],
  ['tw-nt', 1],
  ['tw-tw', 1],
  ['tw-tp', 1],
]
var data_series = [{
  name: 'orange',
  data: data_orange
}, {
  name: 'cabbage',
  data: data_cabbage
}, {
  name: 'peanut',
  data: data_peanut
}, {
  name: 'All',
  data: all_data,
}];
var chart;

function createChart(chartData) {
  // Instanciate the map
  chart = new Highcharts.mapChart('container', {
    chart: {
      borderWidth: 1
    },

    title: {
      text: 'December product map'
    },
    subtitle: {
      text: 'https://stackoverflow.com/questions/47646879/cant-show-the-color-in-interactive-highchart-choropleth-map'
    },

    legend: {
      enabled: false
    },
    mapNavigation: {
      enabled: true,
      buttonOptions: {
        verticalAlign: 'bottom'
      }
    },
    series: [{
      name: 'Country',
      mapData: Highcharts.maps['countries/tw/tw-all'],
      data: chartData,
      dataLabels: {
        enabled: true,
        color: '#FFFFFF',
        formatter: function() {
          if (this.point.value) {
            return this.point.name;
          }
        }
      },
      tooltip: {
        headerFormat: '',
        pointFormat: '{point.name}'
      }
    }]
  });

}

window.updateChart = function(selection) {
  if (selection == "") {
    createChart(data_series[3].data);
  } else if (selection == "orange") {
    createChart(data_series[0].data)

  } else if (selection == "cabbage") {
    createChart(data_series[1].data)
  } else if (selection == "peanut") {
    createChart(data_series[2].data)
  }

}

//start rendering----------------------------------------------
updateChart("");

<script src="https://code.highcharts.com/maps/highmaps.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/tw/tw-all.js"></script>

<div align="center" style="font-size:110%">
  Product:
  <select name='location' onchange="updateChart(this.value)" style="font-size:110%">
    <option value="" selected value="">Select</option>
    <option value="orange">Orange</option>
    <option value="cabbage">Cabbage</option>
    <option value="peanut">Peanut</option>
  </select>
</div>
<br>
<div id="container" style="height: 500px; min-width: 310px; max-width: 600px; margin: 0 auto"></div>


问:
How to add virtualenv to path
I am trying to find out why my virtualenv and/or virtualenv wrapper - installed using pip using homebrew - cannot be found. I think it's because it's not added to my PATH:

```<code>$ which virtualenv
$
</code>```

and:

```<code>$ virtualenv someDir
$ -bash: virtualenv: command not found
</code>```

I installed pip using homebrew, and virtualenv using pip, without problems. I tried reinstalling virtualenv, but that did not work either.
How do I know what path to add to PATH? Just the path that virtualenv.py seems to be installed into? That seems to be:

```<code>/usr/local/lib/python2.7/site-packages/virtualenv.py
</code>```

I also found this guide, which suggests this:

```<code>$ ln -s ../Cellar/python/2.7/Frameworks/Python.framework/Versions/2.7/bin/virtualenv virtualenv
</code>```

However, it does not help me run virtualenv. I am on Mac OSX 10.7.5 (Lion).

答:
I solved it by:
At first, I found out it is located at /usr/local/python3
and then I fixed it by the command:

ln virtualenv /usr/local/bin/virtualenv
```

Title: How to add virtualenv to path

Body:
I am trying to find out why my virtualenv and/or virtualenv wrapper - installed using pip using homebrew - cannot be found. I think it's because it's not added to my PATH:

$ which virtualenv
$

and:

$ virtualenv someDir
$ -bash: virtualenv: command not found

I installed pip using homebrew, and virtualenv using pip, without problems. I tried reinstalling virtualenv, but that did not work either.
How do I know what path to add to PATH? Just the path that virtualenv.py seems to be installed into? That seems to be:

/usr/local/lib/python2.7/site-packages/virtualenv.py

I also found this guide, which suggests this:

$ ln -s ../Cellar/python/2.7/Frameworks/Python.framework/Versions/2.7/bin/virtualenv virtualenv

However, it does not help me run virtualenv. I am on Mac OSX 10.7.5 (Lion).


问:
Debugging Affectiva FrameDetector: Worker Code Reported an Exception
I'm trying to use FrameDetector to process an existing MP4 file.  I've put the video file and the HTML/JavaScript below inside a node.js server and run it at localhost, so there shouldn't be aby CORS issues.

The detector starts correctly, but when I send image data to it, the same two things happen every time:

The first request returns an empty faces array

The second request returns an error (with a unique, trailing number each time): worker code reported an exception14920304.

I'm not really sure what to do with that message- does anyone have any suggestions?

```<code>//- FrameDetector.pug
html
  head
    title FrameDetector Demo
    script(src='https://download.affectiva.com/js/3.2/affdex.js')
  body
    canvas#canvas
    video#video-to-analyze(preload="auto" controls="true")
      source(type="video/mp4" src="video/my-video.mp4")
    script(src='js/FrameDetector.js')
</code>```

and

```<code>// FrameDetector.js
var heartbeat, startTimestamp;

document.addEventListener('DOMContentLoaded', function(){
  var v = document.getElementById('video-to-analyze');
  var canvas = document.getElementById('canvas');
  var context = canvas.getContext('2d');

  var cw = Math.floor(canvas.clientWidth / 100);
  var ch = Math.floor(canvas.clientHeight / 100);
  canvas.width = cw;
  canvas.height = ch;

  v.addEventListener('play', function(){
      draw(this,context,cw,ch);
  },false);

},false);

function draw(v,c,w,h) {
  if(v.paused || v.ended) return false;
  c.drawImage(v,0,0,w,h);
  setTimeout(draw,20,v,c,w,h);
}

function analyzeVideoFrame() {
  //Get a canvas element from DOM
  var aCanvas = document.getElementById("canvas");
  var context = aCanvas.getContext('2d');

  //Get imageData object.
  var imageData = context.getImageData(0, 0, 640, 360);
  console.log("Captured imageData.", imageData);

  //Get current time in seconds
  var now = (new Date()).getTime() / 1000;

  //Get delta time between the first frame and the current frame.
  var deltaTime = now - startTimestamp;

  //Process the frame
  detector.process(imageData, deltaTime);
}

function onImageResultsSuccess(faces, image, timestamp) {
  console.log("onImageResultsSuccess:", timestamp, faces.length, faces[0]);
}

function onImageResultsFailure(image, timestamp, err_detail) {
  console.error("onImageResultsFailure:", timestamp, err_detail);
  clearInterval(heartbeat);
}

if (typeof(affdex)=="undefined") {
  console.log("The affdex global variable has not been loaded.");
}

var detector = new affdex.FrameDetector(affdex.FaceDetectorMode.LARGE_FACES);

detector.detectAllExpressions();
detector.detectAllEmotions();
detector.detectAllAppearance();

detector.addEventListener("onInitializeSuccess", function() {
  document.getElementById('video-to-analyze').play();
  startTimestamp = (new Date()).getTime() / 1000;
  heartbeat = setInterval(analyzeVideoFrame, 1000);
});
detector.addEventListener("onInitializeFailure", function() {
  console.error("Affectiva failed to initialize.");
});

detector.addEventListener("onImageResultsSuccess", onImageResultsSuccess);
detector.addEventListener("onImageResultsFailure", onImageResultsFailure);

detector.start();
</code>```

Output in the console:

```<code>Captured imageData. ImageData {data: Uint8ClampedArray(921600), width: 640, height: 360}
onImageResultsSuccess: 0.005000114440917969 0 undefined
Captured imageData. ImageData {data: Uint8ClampedArray(921600), width: 640, height: 360}
onImageResultsFailure: 0.0009999275207519531 worker code reported an exception14920304
</code>```

答:
Got it.  Once I got the image drawn correctly to the canvas element, the Affectiva code worked fine.  Here's a my corrected code:

```<code>//- FrameDetector.pug
html
  head
    title FrameDetector Demo
    script(src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js')
    script(src='https://download.affectiva.com/js/3.2/affdex.js')
  body
    canvas#canvas(width="640" height="360" style="display:none;")
    video#video(preload="auto" controls="true")
      source(type="video/mp4" src="video/my-video.mp4")
    script(src='js/FrameDetector.js')
</code>```

and

```<code>// FrameDetector.js
var heartbeat, startTimestamp;

function onVideoPlay() {
  var $this = this; //cache
  (function loop() {
    if (!$this.paused && !$this.ended) {
      ctx.drawImage($this, 0, 0);
      setTimeout(loop, 1000 / 30); // drawing at 30fps
    }
  })();
}

function analyzeVideoFrame() {
  //Get a canvas element from DOM
  var aCanvas = document.getElementById("canvas");
  var context = aCanvas.getContext('2d');

  //Get imageData object.
  var imageData = context.getImageData(0, 0, 640, 360);
  console.log("Captured imageData.", imageData);

  //Get current time in seconds
  var now = (new Date()).getTime() / 1000;

  //Get delta time between the first frame and the current frame.
  var deltaTime = now - startTimestamp;

  //Process the frame
  detector.process(imageData, deltaTime);
}

function onImageResultsSuccess(faces, image, timestamp) {
  console.log("onImageResultsSuccess:", timestamp, faces.length, faces[0]);
}

function onImageResultsFailure(image, timestamp, err_detail) {
  console.error("onImageResultsFailure:", timestamp, err_detail);
  clearInterval(heartbeat);
}

$(function() {
  if (typeof(affdex)=="undefined") {
    console.log("The affdex global variable has not been loaded.");
  }

  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  var video = document.getElementById('video');
  var detector = new affdex.FrameDetector(affdex.FaceDetectorMode.LARGE_FACES);

  // Set up a loop to draw frames to the canvas element
  video.addEventListener('play', onVideoPlay, 0);

  // Set up and start the detector
  detector.detectAllExpressions();
  detector.detectAllEmotions();
  detector.detectAllAppearance();

  detector.addEventListener("onInitializeSuccess", function() {
    document.getElementById('video').play();
    startTimestamp = (new Date()).getTime() / 1000;
    heartbeat = setInterval(analyzeVideoFrame, 1000);
  });
  detector.addEventListener("onInitializeFailure", function() {
    console.error("Affectiva failed to initialize.");
  });

  detector.addEventListener("onImageResultsSuccess", onImageResultsSuccess);
  detector.addEventListener("onImageResultsFailure", onImageResultsFailure);

  detector.start();
});
</code>```

Body:
I'm trying to use FrameDetector to process an existing MP4 file.  I've put the video file and the HTML/JavaScript below inside a node.js server and run it at localhost, so there shouldn't be aby CORS issues.

The detector starts correctly, but when I send image data to it, the same two things happen every time:

The first request returns an empty faces array

The second request returns an error (with a unique, trailing number each time): worker code reported an exception14920304.

I'm not really sure what to do with that message- does anyone have any suggestions?

//- FrameDetector.pug
html
  head
    title FrameDetector Demo
    script(src='https://download.affectiva.com/js/3.2/affdex.js')
  body
    canvas#canvas
    video#video-to-analyze(preload="auto" controls="true")
      source(type="video/mp4" src="video/my-video.mp4")
    script(src='js/FrameDetector.js')

and

// FrameDetector.js
var heartbeat, startTimestamp;

document.addEventListener('DOMContentLoaded', function(){
  var v = document.getElementById('video-to-analyze');
  var canvas = document.getElementById('canvas');
  var context = canvas.getContext('2d');

  var cw = Math.floor(canvas.clientWidth / 100);
  var ch = Math.floor(canvas.clientHeight / 100);
  canvas.width = cw;
  canvas.height = ch;

  v.addEventListener('play', function(){
      draw(this,context,cw,ch);
  },false);

},false);

function draw(v,c,w,h) {
  if(v.paused || v.ended) return false;
  c.drawImage(v,0,0,w,h);
  setTimeout(draw,20,v,c,w,h);
}

function analyzeVideoFrame() {
  //Get a canvas element from DOM
  var aCanvas = document.getElementById("canvas");
  var context = aCanvas.getContext('2d');

  //Get imageData object.
  var imageData = context.getImageData(0, 0, 640, 360);
  console.log("Captured imageData.", imageData);

  //Get current time in seconds
  var now = (new Date()).getTime() / 1000;

  //Get delta time between the first frame and the current frame.
  var deltaTime = now - startTimestamp;

  //Process the frame
  detector.process(imageData, deltaTime);
}

function onImageResultsSuccess(faces, image, timestamp) {
  console.log("onImageResultsSuccess:", timestamp, faces.length, faces[0]);
}

function onImageResultsFailure(image, timestamp, err_detail) {
  console.error("onImageResultsFailure:", timestamp, err_detail);
  clearInterval(heartbeat);
}

if (typeof(affdex)=="undefined") {
  console.log("The affdex global variable has not been loaded.");
}

var detector = new affdex.FrameDetector(affdex.FaceDetectorMode.LARGE_FACES);

detector.detectAllExpressions();
detector.detectAllEmotions();
detector.detectAllAppearance();

detector.addEventListener("onInitializeSuccess", function() {
  document.getElementById('video-to-analyze').play();
  startTimestamp = (new Date()).getTime() / 1000;
  heartbeat = setInterval(analyzeVideoFrame, 1000);
});
detector.addEventListener("onInitializeFailure", function() {
  console.error("Affectiva failed to initialize.");
});

detector.addEventListener("onImageResultsSuccess", onImageResultsSuccess);
detector.addEventListener("onImageResultsFailure", onImageResultsFailure);

detector.start();

Output in the console:

Captured imageData. ImageData {data: Uint8ClampedArray(921600), width: 640, height: 360}
onImageResultsSuccess: 0.005000114440917969 0 undefined
Captured imageData. ImageData {data: Uint8ClampedArray(921600), width: 640, height: 360}
onImageResultsFailure: 0.0009999275207519531 worker code reported an exception14920304

Body:
Got it.  Once I got the image drawn correctly to the canvas element, the Affectiva code worked fine.  Here's a my corrected code:

//- FrameDetector.pug
html
  head
    title FrameDetector Demo
    script(src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js')
    script(src='https://download.affectiva.com/js/3.2/affdex.js')
  body
    canvas#canvas(width="640" height="360" style="display:none;")
    video#video(preload="auto" controls="true")
      source(type="video/mp4" src="video/my-video.mp4")
    script(src='js/FrameDetector.js')

and

// FrameDetector.js
var heartbeat, startTimestamp;

function onVideoPlay() {
  var $this = this; //cache
  (function loop() {
    if (!$this.paused && !$this.ended) {
      ctx.drawImage($this, 0, 0);
      setTimeout(loop, 1000 / 30); // drawing at 30fps
    }
  })();
}

function analyzeVideoFrame() {
  //Get a canvas element from DOM
  var aCanvas = document.getElementById("canvas");
  var context = aCanvas.getContext('2d');

  //Get imageData object.
  var imageData = context.getImageData(0, 0, 640, 360);
  console.log("Captured imageData.", imageData);

  //Get current time in seconds
  var now = (new Date()).getTime() / 1000;

  //Get delta time between the first frame and the current frame.
  var deltaTime = now - startTimestamp;

  //Process the frame
  detector.process(imageData, deltaTime);
}

function onImageResultsSuccess(faces, image, timestamp) {
  console.log("onImageResultsSuccess:", timestamp, faces.length, faces[0]);
}

function onImageResultsFailure(image, timestamp, err_detail) {
  console.error("onImageResultsFailure:", timestamp, err_detail);
  clearInterval(heartbeat);
}

$(function() {
  if (typeof(affdex)=="undefined") {
    console.log("The affdex global variable has not been loaded.");
  }

  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  var video = document.getElementById('video');
  var detector = new affdex.FrameDetector(affdex.FaceDetectorMode.LARGE_FACES);

  // Set up a loop to draw frames to the canvas element
  video.addEventListener('play', onVideoPlay, 0);

  // Set up and start the detector
  detector.detectAllExpressions();
  detector.detectAllEmotions();
  detector.detectAllAppearance();

  detector.addEventListener("onInitializeSuccess", function() {
    document.getElementById('video').play();
    startTimestamp = (new Date()).getTime() / 1000;
    heartbeat = setInterval(analyzeVideoFrame, 1000);
  });
  detector.addEventListener("onInitializeFailure", function() {
    console.error("Affectiva failed to initialize.");
  });

  detector.addEventListener("onImageResultsSuccess", onImageResultsSuccess);
  detector.addEventListener("onImageResultsFailure", onImageResultsFailure);

  detector.start();
});


问:
Efficiently selecting latest charge per patient
I've got three tables in SQL Server 2005 (relevant rows included):

```<code>Patient (560K rows, has many Appts)
    ID (PK, Clustered)
Appt (5.8M rows, has many ApptCPTs)
    ID (PK, Unique, Non-clustered)
    PatientID (Indexed, Non-unique, Non-clustered)
ApptCPT (13.4M rows)
    ID (PK, Clustered)
    ApptID (Indexed, Non-unique, Non-clustered)
    CPTID (Indexed, Non-unique, Non-clustered)
</code>```

I want to get the latest ApptCPT for each CPT code, for each patient, but the query I've got so far takes about a minute to return ~7M rows.

My current query:

```<code>SELECT
    p.ID AS PatientID,
    MAX(ac.ID) AS ApptCPTID,
    ac.CPTID
FROM
    Patient p
INNER JOIN Appt a ON a.PatientID = p.ID
INNER JOIN ApptCPT ac ON ac.ApptID = a.ID
GROUP BY
    p.ID, ac.CPTID
ORDER BY
    p.ID, ac.CPTID
</code>```

Example output:

```<code>PatientID    ApptCPTID    CPTID
123456789    18627724     3088
123456789    7647238      3388
123456789    18627723     3419
123456789    9989220      3419
123456789    12190141     3448
123456789    18627721     3551
123456789    17264224     71020
123456789    15933265     77052
123456789    10095897     77057
123456789    5258166      77080
123456789    18627813     80053
123456789    18627814     80061
</code>```

If I take the MAX out and put ac.ID in the GROUP BY clause, I can see that I'm getting the correct data with my original query, because it's getting the last ApptCPT containing that CPTID for that patient, but it's horribly slow. For reference, here's the same output not using the MAX clause:

```<code>PatientID    ApptCPTID    CPTID
123456789    18126508     3088
123456789    4596004      3088
123456789    18627724     3088
123456789    7647238      3388
123456789    18627723     3419
123456789    9989220      3419
123456789    12190141     3448
123456789    4595928      3551
123456789    9989218      3551
123456789    18627721     3551
123456789    17264224     71020
123456789    15933265     77052
123456789    10095897     77057
123456789    5258050      77057
123456789    5258166      77080
123456789    4595932      80053
123456789    18126505     80053
123456789    9989223      80053
123456789    18627813     80053
123456789    18627814     80061
</code>```

Anyone have any ideas for making it (hopefully) much, much faster?

答: You want 7 million records at 12 bytes each (assuming 32-bit ints for each ID column -- your CPT codes are probably larger since my experience there says they can have text components in certain cases).  That's 84 megabytes of raw data, forgetting any management overhead in the protocol.  I think one minute for that data is pretty good -- it will take that long just to transfer that much information to your computer over the network line from the server, which means your query must be handing out results almost instantly.  Pare down your result set and your times will improve.</p>

ContentLicense: CC BY-SA 2.5

Body:
I've got three tables in SQL Server 2005 (relevant rows included):

Patient (560K rows, has many Appts)
    ID (PK, Clustered)
Appt (5.8M rows, has many ApptCPTs)
    ID (PK, Unique, Non-clustered)
    PatientID (Indexed, Non-unique, Non-clustered)
ApptCPT (13.4M rows)
    ID (PK, Clustered)
    ApptID (Indexed, Non-unique, Non-clustered)
    CPTID (Indexed, Non-unique, Non-clustered)

I want to get the latest ApptCPT for each CPT code, for each patient, but the query I've got so far takes about a minute to return ~7M rows.

My current query:

SELECT
    p.ID AS PatientID,
    MAX(ac.ID) AS ApptCPTID,
    ac.CPTID
FROM
    Patient p
INNER JOIN Appt a ON a.PatientID = p.ID
INNER JOIN ApptCPT ac ON ac.ApptID = a.ID
GROUP BY
    p.ID, ac.CPTID
ORDER BY
    p.ID, ac.CPTID

Example output:

PatientID    ApptCPTID    CPTID
123456789    18627724     3088
123456789    7647238      3388
123456789    18627723     3419
123456789    9989220      3419
123456789    12190141     3448
123456789    18627721     3551
123456789    17264224     71020
123456789    15933265     77052
123456789    10095897     77057
123456789    5258166      77080
123456789    18627813     80053
123456789    18627814     80061

If I take the MAX out and put ac.ID in the GROUP BY clause, I can see that I'm getting the correct data with my original query, because it's getting the last ApptCPT containing that CPTID for that patient, but it's horribly slow. For reference, here's the same output not using the MAX clause:

PatientID    ApptCPTID    CPTID
123456789    18126508     3088
123456789    4596004      3088
123456789    18627724     3088
123456789    7647238      3388
123456789    18627723     3419
123456789    9989220      3419
123456789    12190141     3448
123456789    4595928      3551
123456789    9989218      3551
123456789    18627721     3551
123456789    17264224     71020
123456789    15933265     77052
123456789    10095897     77057
123456789    5258050      77057
123456789    5258166      77080
123456789    4595932      80053
123456789    18126505     80053
123456789    9989223      80053
123456789    18627813     80053
123456789    18627814     80061

Anyone have any ideas for making it (hopefully) much, much faster?


问:
Hadoop replace cp with Distcp
The process is copying the files from one hdfs location into another location in SAME cluster. This is working fine but hadoop -cp is taking time. Can it be replace with distcp for same cluster. OR Is there any better solution to increase the performance.</p>

答:
According to the docs distcp works with copying data within the cluster and between the clousters as well:

https://hadoop.apache.org/docs/current/hadoop-distcp/DistCp.html

DistCp Version 2 (distributed copy) is a tool used for large
  inter/intra-cluster copying. (...) The most common invocation of
  DistCp is an inter-cluster copy:

bash$ hadoop distcp hdfs://nn1:8020/foo/bar hdfs://nn2:8020/bar/foo

This will expand the namespace under /foo/bar on nn1 into a temporary
  file, partition its contents among a set of map tasks, and start a
  copy on each NodeManager from nn1 to nn2.

Title: Hadoop replace cp with Distcp


问:
update multiple rows using dbgrid
I'm super new at coding and I'm making a simple apps now.

So as you can see in the pic, I have multiple data in selected date. If I wanted to update every row with different values and do it with save button, what code should I do?

Does my dbgrid need more setting at its properties?

I'm using Delphi 7 and zeos as db connection as well as oracle as db. Thanks in advance.

答:
Use an Update Query

```<code>select "Database"
Update "tablename"
set "colonnename1"="new value, "colonnename1"="new value, ...
where "colonnename"=value
</code>```

this is the update query and while using delphi you can do this :

```<code>begin
uniquery1.clear;
Uniquery1.SQL.Add('update person set name ='''+edit1.Text+''',lastname='''+edit2.Text+''',age='+edit3.Text+',city='''+edit4.Text+''' where date=' + edit5.text);
uniquery1.ExecSQL;
messagedlg('Successfully Modified!',mtinformation,[mbOK],0);
end;
</code>```

Or you can use the parametrized method which is way better then concatenating the SQL As NIL said :

```<code>begin
Uniquery1.sql.clear;
Uniquery1.SQL.Add('UPDATE person SET  "1colonnename"= ":parmID", name= :sal WHERE Num='+ inttostr(strtoint(dbgrid1.DataSource.DataSet.FieldValues['num'])));                             uniquery1.ParamByName('paramID').value:=edit1.text;
uniquery1.ParamByName('sal').Value:=edit2.text;
uniquery1.ExecSQL;
end;
</code>```

This is just an exemple but this how it works !
Good luck

Title: update multiple rows using dbgrid

Body:
Use an Update Query

select "Database"
Update "tablename"
set "colonnename1"="new value, "colonnename1"="new value, ...
where "colonnename"=value

this is the update query and while using delphi you can do this :

begin
uniquery1.clear;
Uniquery1.SQL.Add('update person set name ='''+edit1.Text+''',lastname='''+edit2.Text+''',age='+edit3.Text+',city='''+edit4.Text+''' where date=' + edit5.text);
uniquery1.ExecSQL;
messagedlg('Successfully Modified!',mtinformation,[mbOK],0);
end;

Or you can use the parametrized method which is way better then concatenating the SQL As NIL said :

begin
Uniquery1.sql.clear;
Uniquery1.SQL.Add('UPDATE person SET  "1colonnename"= ":parmID", name= :sal WHERE Num='+ inttostr(strtoint(dbgrid1.DataSource.DataSet.FieldValues['num'])));                             uniquery1.ParamByName('paramID').value:=edit1.text;
uniquery1.ParamByName('sal').Value:=edit2.text;
uniquery1.ExecSQL;
end;

This is just an exemple but this how it works !
Good luck


问:
How to add a blank line in a Manifest file of a jar in gradle
I need to add the data in MANIFEST.MF of jar file in below format .

```<code>Manifest-Version: 1.0

Name: MyService
Service-Class: com.MyService

Packaged-Jars: xmlParserAPIs jython
</code>```

My condition is : The manifest text file must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return. Also, make sure to include a blank line before each class header line (e.g.lines beginning with "Name: (class file)")

What should I do in gradle?

答:
You can work with an escaped newline character like:</p>

```<code>jar {
    manifest {
        attributes(
            'Manifest-Version': 1.0 + "\n",
            'SomeOther': 'test',
            //...
        )
    }
}
</code>```

Body:
I need to add the data in MANIFEST.MF of jar file in below format .

Manifest-Version: 1.0

Name: MyService
Service-Class: com.MyService

Packaged-Jars: xmlParserAPIs jython

My condition is : The manifest text file must end with a new line or carriage return. The last line will not be parsed properly if it does not end with a new line or carriage return. Also, make sure to include a blank line before each class header line (e.g.lines beginning with "Name: (class file)")

What should I do in gradle?

Body:
You can work with an escaped newline character like:

jar {
    manifest {
        attributes(
            'Manifest-Version': 1.0 + "\n",
            'SomeOther': 'test',
            //...
        )
    }
}


问:
Trying to open PDF file from assets folder using fileProvider but it gives FileNotFoundException: No such file or directory
I am trying to display "NEFT.pdf" file stored in the asset folder of my android app.

The following code works absolutely fine till API 25

```<code>private void CopyReadAssets(String filename) {
    AssetManager assetManager = getAssets();
    InputStream in = null;
    OutputStream out = null;
    File file = new File(getFilesDir(), filename);

    try {
        in = assetManager.open(filename);
        out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);

        copyFile(in, out);
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(
                Uri.parse("file://" + getFilesDir() + "/"+filename), "application/pdf");

        startActivity(intent);
    } catch (Exception e)
    {
        Toast.makeText(PdfFilesList.this, "cra: "+e.toString(), Toast.LENGTH_SHORT).show();
    }
}
</code>```

This code does not work on API 25 and above. It gives the error MODE_WORLD_READABLE no longer supported.

I changed it to MODE_PRIVATE but that gives me another error

android.os.fileuriexposedexception exposed beyond app through intent.getdata().

So I applied the concept explained at Developer.Android.com.

This is what I get in the error log:

E/DisplayData: openFd: java.io.FileNotFoundException: No such file or directory

E/PdfLoader: Can't load file (doesn't open)  Display Data [PDF : NEFT.pdf] +ContentOpenable, uri: content://com.user.plansmart.provider/pdf_files/NEFT.pdf

uri looks correct to me. Can Anyone help me in locating the error here.

Here is the provider element in the manifest file.

```<code><provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>
</code>```

This is the provider_paths.xml file

```<code><?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
<files-path name="pdf_files" path="pdf/"/>
</code>```

This is the Android code to display the pdf file

```<code>private void displayFile(String filename) {
    try {
        File filePath = new File(getApplicationContext().getFilesDir(), "pdf");
        File newFile =  new File(filePath, filename);

        //new version
        Uri fileUri = FileProvider.getUriForFile(PdfFilesList.this,
                BuildConfig.APPLICATION_ID + ".provider", newFile);

        getApplicationContext().grantUriPermission(PACKAGE_NAME,
                            fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(fileUri, "application/pdf");
        intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);
        startActivity(intent);
    }catch (Exception e){
        e.printStackTrace();
        Toast.makeText(PdfFilesList.this, "df "+e.toString(), Toast.LENGTH_SHORT).show();
    }
}
</code>```

答:
Cause you wanna display the PDF file  in a separate application (such as Adobe Reader), I would prefer doing the following:-

```<code>private void CopyReadAssets()
        {
            AssetManager assetManager = getActivity().getAssets();

            InputStream in = null;
            OutputStream out = null;
            String state = Environment.getExternalStorageState();
            if (!Environment.MEDIA_MOUNTED.equals(state)) {
                Toast.makeText(getActivity(), "External Storage is not Available", Toast.LENGTH_SHORT).show();
            }
            File pdfDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/PDFs");
            if (!pdfDir.exists()) {
                pdfDir.mkdir();
            }
            File file = new File(pdfDir + "/abc.pdf");

            try
            {
                in = assetManager.open("abc.pdf");
                out = new BufferedOutputStream(new FileOutputStream(file));
                copyFile(in, out);
                in.close();
                in = null;
                out.flush();
                out.close();
                out = null;
            } catch (Exception e)
            {
                Log.e("tag", e.getMessage());
            }
            if (file.exists()) //Checking for the file is exist or not
            {
                Uri path = Uri.fromFile(file);
                Intent objIntent = new Intent(Intent.ACTION_VIEW);
                objIntent.setDataAndType(path, "application/pdf");
                objIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                Intent intent1 = Intent.createChooser(objIntent, "Open PDF with..");
                try {
                    startActivity(intent1);
                } catch (ActivityNotFoundException e) {
                    Toast.makeText(getActivity(), "Activity Not Found Exception ", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(getActivity(), "The file not exists! ", Toast.LENGTH_SHORT).show();
            }
        }
</code>```

For copy file into device memory:-

```<code>private void copyFile(InputStream in, OutputStream out) throws IOException
    {
        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1)
        {
            out.write(buffer, 0, read);
        }
    }
</code>```

Use the below Permission

```<code><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</code>```

Body:
I am trying to display "NEFT.pdf" file stored in the asset folder of my android app.

The following code works absolutely fine till API 25

private void CopyReadAssets(String filename) {
    AssetManager assetManager = getAssets();
    InputStream in = null;
    OutputStream out = null;
    File file = new File(getFilesDir(), filename);

    try {
        in = assetManager.open(filename);
        out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);

        copyFile(in, out);
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(
                Uri.parse("file://" + getFilesDir() + "/"+filename), "application/pdf");

        startActivity(intent);
    } catch (Exception e)
    {
        Toast.makeText(PdfFilesList.this, "cra: "+e.toString(), Toast.LENGTH_SHORT).show();
    }
}

This code does not work on API 25 and above. It gives the error MODE_WORLD_READABLE no longer supported.

I changed it to MODE_PRIVATE but that gives me another error

android.os.fileuriexposedexception exposed beyond app through intent.getdata().

So I applied the concept explained at Developer.Android.com.

This is what I get in the error log:

E/DisplayData: openFd: java.io.FileNotFoundException: No such file or directory

E/PdfLoader: Can't load file (doesn't open)  Display Data [PDF : NEFT.pdf] +ContentOpenable, uri: content://com.user.plansmart.provider/pdf_files/NEFT.pdf

uri looks correct to me. Can Anyone help me in locating the error here.

Here is the provider element in the manifest file.

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

This is the provider_paths.xml file

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
<files-path name="pdf_files" path="pdf/"/>

This is the Android code to display the pdf file

private void displayFile(String filename) {
    try {
        File filePath = new File(getApplicationContext().getFilesDir(), "pdf");
        File newFile =  new File(filePath, filename);

        //new version
        Uri fileUri = FileProvider.getUriForFile(PdfFilesList.this,
                BuildConfig.APPLICATION_ID + ".provider", newFile);

        getApplicationContext().grantUriPermission(PACKAGE_NAME,
                            fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(fileUri, "application/pdf");
        intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);
        startActivity(intent);
    }catch (Exception e){
        e.printStackTrace();
        Toast.makeText(PdfFilesList.this, "df "+e.toString(), Toast.LENGTH_SHORT).show();
    }
}

Body:
Cause you wanna display the PDF file  in a separate application (such as Adobe Reader), I would prefer doing the following:-

private void CopyReadAssets()
        {
            AssetManager assetManager = getActivity().getAssets();

            InputStream in = null;
            OutputStream out = null;
            String state = Environment.getExternalStorageState();
            if (!Environment.MEDIA_MOUNTED.equals(state)) {
                Toast.makeText(getActivity(), "External Storage is not Available", Toast.LENGTH_SHORT).show();
            }
            File pdfDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/PDFs");
            if (!pdfDir.exists()) {
                pdfDir.mkdir();
            }
            File file = new File(pdfDir + "/abc.pdf");

            try
            {
                in = assetManager.open("abc.pdf");
                out = new BufferedOutputStream(new FileOutputStream(file));
                copyFile(in, out);
                in.close();
                in = null;
                out.flush();
                out.close();
                out = null;
            } catch (Exception e)
            {
                Log.e("tag", e.getMessage());
            }
            if (file.exists()) //Checking for the file is exist or not
            {
                Uri path = Uri.fromFile(file);
                Intent objIntent = new Intent(Intent.ACTION_VIEW);
                objIntent.setDataAndType(path, "application/pdf");
                objIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                Intent intent1 = Intent.createChooser(objIntent, "Open PDF with..");
                try {
                    startActivity(intent1);
                } catch (ActivityNotFoundException e) {
                    Toast.makeText(getActivity(), "Activity Not Found Exception ", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(getActivity(), "The file not exists! ", Toast.LENGTH_SHORT).show();
            }
        }

For copy file into device memory:-

private void copyFile(InputStream in, OutputStream out) throws IOException
    {
        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1)
        {
            out.write(buffer, 0, read);
        }
    }

Use the below Permission

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


问:
How to Capture Screenshot of an Surface View
```<code>public class CustomCameraActivity extends Activity implements
        SurfaceHolder.Callback {
    Camera camera = null;
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    boolean previewing = false;
    int flag = 0;
    int which = 0;
    Handler handler;
    private boolean hasFlash;
    private boolean isLighOn;
    private Bitmap surfaceBitmap;
    private Bitmap cameraBitmap;
    private VerticalSeekBar greenSeekbar;
    int vesion = 0;

    public void turn() {
        // myCamera is the Camera object
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
            // only for android older than gingerbread

            if (Camera.getNumberOfCameras() >= 2) {
                vesion = 1;
                camera.stopPreview();
                camera.release();
                // "which" is just an integer flag
                switch (which) {
                case 0:
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
                    which = 1;
                    break;
                case 1:
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
                    which = 0;
                    break;
                }
                try {
                    camera.setPreviewDisplay(surfaceHolder);
                    // "this" is a SurfaceView which implements
                    // SurfaceHolder.Callback,
                    // as found in the code examples
                    camera.setPreviewCallback(null);
                    // camera.setPreviewCallback(this);
                    camera.startPreview();
                } catch (IOException exception) {
                    camera.release();
                    camera = null;
                }
                vesion = 1;
            } else {
                AlertDialog.Builder ab = new AlertDialog.Builder(
                        CustomCameraActivity.this);
                ab.setMessage("Device Having Only one Camera");
                ab.setCancelable(false);
                ab.setPositiveButton("ok",
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                    int which) {
                                // TODO Auto-generated method stub

                            }
                        }).show();

            }
        } else {
            AlertDialog.Builder ab1 = new AlertDialog.Builder(
                    CustomCameraActivity.this);
            ab1.setMessage("This Device Does Not Support Dual Camera Feature");
            ab1.setCancelable(false);
            ab1.setPositiveButton("ok", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // TODO Auto-generated method stub

                }
            }).show();
        }
    }

    private PictureCallback mPicture = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            Constants.data1 = data;
        }

    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getWindow().setFormat(PixelFormat.UNKNOWN);
        surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(3);
        this.surfaceView.setBackgroundColor(Color.argb(100, 0,
                MotionEventCompat.ACTION_MASK, 0));

        Button cap_btn = (Button) findViewById(R.id.button01);
        Button retake = (Button) findViewById(R.id.retake);
        Button use = (Button) findViewById(R.id.Use);
        Button back = (Button) findViewById(R.id.back);
        Button home = (Button) findViewById(R.id.home);
        Button turn = (Button) findViewById(R.id.turn);
        turn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                turn();
            }
        });
        home.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                flash();
            }
        });
        back.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                finish();
            }
        });
        use.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (flag >= 1) {
                    startActivity(new Intent(CustomCameraActivity.this,
                            Captured.class));
                } else {
                    AlertDialog.Builder ab1 = new AlertDialog.Builder(
                            CustomCameraActivity.this);
                    ab1.setMessage("Please Capture Image");
                    ab1.setCancelable(false);
                    ab1.setPositiveButton("ok",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    // TODO Auto-generated method stub

                                }
                            }).show();
                }
                flag = 0;
            }
        });
        retake.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                camera.startPreview();
                flag = 0;
            }
        });

        cap_btn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                camera.takePicture(null, null, mPicture);
                flag++;
            }
        });
    }

    public void flash() {
        this.hasFlash = getApplicationContext().getPackageManager()
                .hasSystemFeature("android.hardware.camera.flash");
        if (this.hasFlash) {
            Parameters p = camera.getParameters();
            if (this.isLighOn) {
                p.setFlashMode("off");
                camera.setParameters(p);
                camera.stopPreview();
                camera.startPreview();
                this.isLighOn = false;
                return;
            }
            p.setFlashMode("torch");
            camera.setParameters(p);
            camera.stopPreview();
            camera.startPreview();
            this.isLighOn = true;
            return;
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        if (previewing) {
            camera.stopPreview();
            previewing = false;

        }

        if (camera != null) {
            try {
                camera.setPreviewDisplay(surfaceHolder);

                camera.startPreview();
                previewing = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    void setCameraDisplayOrientation(Activity activity, int cameraId,
            Camera camera) {
        if (camera != null) {
            int result;
            CameraInfo info = new CameraInfo();
            int degrees = 0;
            switch (activity.getWindowManager().getDefaultDisplay()
                    .getRotation()) {
            case 0:
                degrees = 0;
                break;
            case 1:
                degrees = 90;
                break;
            case 2:
                degrees = 180;
                break;
            case 3:
                degrees = 270;
                break;
            }
            if (info.facing == 1) {
                result = (360 - ((info.orientation + degrees) % 360)) % 360;
            } else {
                result = ((info.orientation - degrees) + 360) % 360;
            }
            camera.setDisplayOrientation(result);
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            if (vesion == 1) {
                Camera.open(which);
            } else {
                camera = Camera.open();
            }
        } catch (Exception e) {
            camera.release();
        }
        try {
            Parameters parameters = camera.getParameters();
            if (getResources().getConfiguration().orientation != 2) {
                parameters.set("orientation", "portrait");
                camera.setDisplayOrientation(90);
                parameters.setRotation(90);
            } else {
                parameters.set("orientation", "landscape");
                camera.setDisplayOrientation(0);
                parameters.setRotation(0);
            }
            camera.setParameters(parameters);
            camera.setPreviewDisplay(this.surfaceHolder);
        } catch (IOException e2) {
            camera.release();
        }
        camera.startPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        camera.release();
        camera = null;
        previewing = false;
    }

    public void joinBitmap() {
        this.surfaceView.setBackgroundColor(-16711936);
        this.surfaceView.setDrawingCacheEnabled(true);
        this.surfaceView.buildDrawingCache();
        this.surfaceView.refreshDrawableState();
        new Thread() {
            public void run() {
                try {
                    CustomCameraActivity.this.surfaceBitmap = CustomCameraActivity.this.surfaceView
                            .getDrawingCache();
                    if (CustomCameraActivity.this.surfaceBitmap != null) {
                        File pictureFile = CustomCameraActivity
                                .getOutputMediaFile();
                        if (pictureFile != null) {
                            Bitmap finalbitmap = CustomCameraActivity.overlay(
                                    CustomCameraActivity.this.cameraBitmap,
                                    CustomCameraActivity.this.surfaceBitmap,
                                    CustomCameraActivity.this.greenSeekbar
                                            .getProgress() + 15);
                            if (pictureFile.exists()) {
                                pictureFile.delete();
                            }
                            try {
                                FileOutputStream out = new FileOutputStream(
                                        pictureFile);
                                finalbitmap.compress(CompressFormat.JPEG, 90,
                                        out);
                                out.flush();
                                out.close();
                            } catch (FileNotFoundException e) {
                            } catch (IOException e2) {
                            }
                            CustomCameraActivity.this.handler
                                    .sendEmptyMessage(1);
                            return;
                        }
                        return;
                    }
                    CustomCameraActivity.this.handler.sendEmptyMessage(0);
                } catch (Exception e3) {
                }
            }
        }.start();
    }

    @SuppressLint({ "SimpleDateFormat" })
    private static File getOutputMediaFile() {
        File mediaStorageDir = new File(
                Environment.getExternalStorageDirectory(),
                "Night Vision Camera");
        if (mediaStorageDir.exists() || mediaStorageDir.mkdirs()) {
            return new File(
                    mediaStorageDir.getPath()
                            + File.separator
                            + "IMG_"
                            + new SimpleDateFormat("yyyyMMdd_HHmmss")
                                    .format(new Date()) + ".jpg");
        }
        return null;
    }

    public static Bitmap overlay(Bitmap bitmap1, Bitmap bitmapOverlay,
            int opacity) {
        Bitmap resultBitmap = Bitmap.createBitmap(bitmapOverlay.getWidth(),
                bitmapOverlay.getHeight(), Config.ARGB_8888);
        Canvas c = new Canvas(resultBitmap);
        c.drawBitmap(bitmap1, 0.0f, 0.0f, null);
        Paint p = new Paint();
        p.setAlpha(opacity);
        c.drawBitmap(bitmapOverlay, 0.0f, 0.0f, p);
        return resultBitmap;
    }
}
</code>```

Here, I`m creating an image overlay on surface view and when i click on image to capture it, how to save it with that image that is overlayed on it? Please help and thanks in Advance. The image is captured but it is not saved with that image that is overlayed on the surface view.

答:
surfaceview.getDrawingCache();  does not work on surface, because surface is separate view than others view you have to get bitmpa on picturetaken method.</p>

```<code> jpegCallback = new PictureCallback() {

        public void onPictureTaken(byte[] data, Camera camera) {

            camera.startPreview();
            Bitmap cameraBitmap = BitmapFactory.decodeByteArray
                    (data, 0, data.length);
            Matrix matrix = new Matrix();
            matrix.postRotate(90);
            pd = new ProgressDialog(MainActivity.this);
            pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            pd.setTitle("Wait!");
            pd.setMessage("capturing image.........");
            pd.setIndeterminate(false);
            pd.show();

            progressStatus = 0;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (progressStatus < 100) {
                        // Update the progress status
                        progressStatus += 1;

                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                // Update the progress status
                                pd.setProgress(progressStatus);
                                // If task execution completed
                                if (progressStatus == 100) {
                                    // Dismiss/hide the progress dialog
                                    pd.dismiss();
                                }
                            }
                        });
                    }
                }
            }).start();

            Bitmap rotatedBitmap = Bitmap.createBitmap(cameraBitmap, 0, 0, cameraBitmap.getWidth(), cameraBitmap.getHeight(), matrix, true);
            if (rotatedBitmap != null) {
                rotatedBitmap = combinebitmap(rotatedBitmap, bitmapMap);
                Random num = new Random();
                int nu = num.nextInt(1000);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
                byte[] bitmapdata = bos.toByteArray();
                ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
                String picId = String.valueOf(nu);
                String myfile = "Ghost" + picId + ".jpeg";
                File dir_image = new File(Environment.getExternalStorageDirectory() +//<---
                        File.separator + "LiveCamera");          //<---
                dir_image.mkdirs();                                                  //<---

                try {
                    File tmpFile = new File(dir_image, myfile);
                    FileOutputStream fos = new FileOutputStream(tmpFile);

                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = fis.read(buf)) > 0) {
                        fos.write(buf, 0, len);
                    }
                    fis.close();
                    fos.close();
                    Toast.makeText(getApplicationContext(),
                            " Image saved at :LiveCamera", Toast.LENGTH_LONG).show();
                    camera.startPreview();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                MediaScannerConnection.scanFile(MainActivity.this,
                        new String[]{dir_image.toString()}, null,
                        new MediaScannerConnection.OnScanCompletedListener() {
                            public void onScanCompleted(String path, Uri uri) {
                            }
                        });

                safeToTakePicture = true;

            }

        }

    };
</code>```

Body:
public class CustomCameraActivity extends Activity implements
        SurfaceHolder.Callback {
    Camera camera = null;
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    boolean previewing = false;
    int flag = 0;
    int which = 0;
    Handler handler;
    private boolean hasFlash;
    private boolean isLighOn;
    private Bitmap surfaceBitmap;
    private Bitmap cameraBitmap;
    private VerticalSeekBar greenSeekbar;
    int vesion = 0;

    public void turn() {
        // myCamera is the Camera object
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
            // only for android older than gingerbread

            if (Camera.getNumberOfCameras() >= 2) {
                vesion = 1;
                camera.stopPreview();
                camera.release();
                // "which" is just an integer flag
                switch (which) {
                case 0:
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
                    which = 1;
                    break;
                case 1:
                    camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
                    which = 0;
                    break;
                }
                try {
                    camera.setPreviewDisplay(surfaceHolder);
                    // "this" is a SurfaceView which implements
                    // SurfaceHolder.Callback,
                    // as found in the code examples
                    camera.setPreviewCallback(null);
                    // camera.setPreviewCallback(this);
                    camera.startPreview();
                } catch (IOException exception) {
                    camera.release();
                    camera = null;
                }
                vesion = 1;
            } else {
                AlertDialog.Builder ab = new AlertDialog.Builder(
                        CustomCameraActivity.this);
                ab.setMessage("Device Having Only one Camera");
                ab.setCancelable(false);
                ab.setPositiveButton("ok",
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                    int which) {
                                // TODO Auto-generated method stub

                            }
                        }).show();

            }
        } else {
            AlertDialog.Builder ab1 = new AlertDialog.Builder(
                    CustomCameraActivity.this);
            ab1.setMessage("This Device Does Not Support Dual Camera Feature");
            ab1.setCancelable(false);
            ab1.setPositiveButton("ok", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // TODO Auto-generated method stub

                }
            }).show();
        }
    }

    private PictureCallback mPicture = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            Constants.data1 = data;
        }

    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getWindow().setFormat(PixelFormat.UNKNOWN);
        surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(3);
        this.surfaceView.setBackgroundColor(Color.argb(100, 0,
                MotionEventCompat.ACTION_MASK, 0));

        Button cap_btn = (Button) findViewById(R.id.button01);
        Button retake = (Button) findViewById(R.id.retake);
        Button use = (Button) findViewById(R.id.Use);
        Button back = (Button) findViewById(R.id.back);
        Button home = (Button) findViewById(R.id.home);
        Button turn = (Button) findViewById(R.id.turn);
        turn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                turn();
            }
        });
        home.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                flash();
            }
        });
        back.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                finish();
            }
        });
        use.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (flag >= 1) {
                    startActivity(new Intent(CustomCameraActivity.this,
                            Captured.class));
                } else {
                    AlertDialog.Builder ab1 = new AlertDialog.Builder(
                            CustomCameraActivity.this);
                    ab1.setMessage("Please Capture Image");
                    ab1.setCancelable(false);
                    ab1.setPositiveButton("ok",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    // TODO Auto-generated method stub

                                }
                            }).show();
                }
                flag = 0;
            }
        });
        retake.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                camera.startPreview();
                flag = 0;
            }
        });

        cap_btn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                camera.takePicture(null, null, mPicture);
                flag++;
            }
        });
    }

    public void flash() {
        this.hasFlash = getApplicationContext().getPackageManager()
                .hasSystemFeature("android.hardware.camera.flash");
        if (this.hasFlash) {
            Parameters p = camera.getParameters();
            if (this.isLighOn) {
                p.setFlashMode("off");
                camera.setParameters(p);
                camera.stopPreview();
                camera.startPreview();
                this.isLighOn = false;
                return;
            }
            p.setFlashMode("torch");
            camera.setParameters(p);
            camera.stopPreview();
            camera.startPreview();
            this.isLighOn = true;
            return;
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        if (previewing) {
            camera.stopPreview();
            previewing = false;

        }

        if (camera != null) {
            try {
                camera.setPreviewDisplay(surfaceHolder);

                camera.startPreview();
                previewing = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    void setCameraDisplayOrientation(Activity activity, int cameraId,
            Camera camera) {
        if (camera != null) {
            int result;
            CameraInfo info = new CameraInfo();
            int degrees = 0;
            switch (activity.getWindowManager().getDefaultDisplay()
                    .getRotation()) {
            case 0:
                degrees = 0;
                break;
            case 1:
                degrees = 90;
                break;
            case 2:
                degrees = 180;
                break;
            case 3:
                degrees = 270;
                break;
            }
            if (info.facing == 1) {
                result = (360 - ((info.orientation + degrees) % 360)) % 360;
            } else {
                result = ((info.orientation - degrees) + 360) % 360;
            }
            camera.setDisplayOrientation(result);
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            if (vesion == 1) {
                Camera.open(which);
            } else {
                camera = Camera.open();
            }
        } catch (Exception e) {
            camera.release();
        }
        try {
            Parameters parameters = camera.getParameters();
            if (getResources().getConfiguration().orientation != 2) {
                parameters.set("orientation", "portrait");
                camera.setDisplayOrientation(90);
                parameters.setRotation(90);
            } else {
                parameters.set("orientation", "landscape");
                camera.setDisplayOrientation(0);
                parameters.setRotation(0);
            }
            camera.setParameters(parameters);
            camera.setPreviewDisplay(this.surfaceHolder);
        } catch (IOException e2) {
            camera.release();
        }
        camera.startPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        camera.release();
        camera = null;
        previewing = false;
    }

    public void joinBitmap() {
        this.surfaceView.setBackgroundColor(-16711936);
        this.surfaceView.setDrawingCacheEnabled(true);
        this.surfaceView.buildDrawingCache();
        this.surfaceView.refreshDrawableState();
        new Thread() {
            public void run() {
                try {
                    CustomCameraActivity.this.surfaceBitmap = CustomCameraActivity.this.surfaceView
                            .getDrawingCache();
                    if (CustomCameraActivity.this.surfaceBitmap != null) {
                        File pictureFile = CustomCameraActivity
                                .getOutputMediaFile();
                        if (pictureFile != null) {
                            Bitmap finalbitmap = CustomCameraActivity.overlay(
                                    CustomCameraActivity.this.cameraBitmap,
                                    CustomCameraActivity.this.surfaceBitmap,
                                    CustomCameraActivity.this.greenSeekbar
                                            .getProgress() + 15);
                            if (pictureFile.exists()) {
                                pictureFile.delete();
                            }
                            try {
                                FileOutputStream out = new FileOutputStream(
                                        pictureFile);
                                finalbitmap.compress(CompressFormat.JPEG, 90,
                                        out);
                                out.flush();
                                out.close();
                            } catch (FileNotFoundException e) {
                            } catch (IOException e2) {
                            }
                            CustomCameraActivity.this.handler
                                    .sendEmptyMessage(1);
                            return;
                        }
                        return;
                    }
                    CustomCameraActivity.this.handler.sendEmptyMessage(0);
                } catch (Exception e3) {
                }
            }
        }.start();
    }

    @SuppressLint({ "SimpleDateFormat" })
    private static File getOutputMediaFile() {
        File mediaStorageDir = new File(
                Environment.getExternalStorageDirectory(),
                "Night Vision Camera");
        if (mediaStorageDir.exists() || mediaStorageDir.mkdirs()) {
            return new File(
                    mediaStorageDir.getPath()
                            + File.separator
                            + "IMG_"
                            + new SimpleDateFormat("yyyyMMdd_HHmmss")
                                    .format(new Date()) + ".jpg");
        }
        return null;
    }

    public static Bitmap overlay(Bitmap bitmap1, Bitmap bitmapOverlay,
            int opacity) {
        Bitmap resultBitmap = Bitmap.createBitmap(bitmapOverlay.getWidth(),
                bitmapOverlay.getHeight(), Config.ARGB_8888);
        Canvas c = new Canvas(resultBitmap);
        c.drawBitmap(bitmap1, 0.0f, 0.0f, null);
        Paint p = new Paint();
        p.setAlpha(opacity);
        c.drawBitmap(bitmapOverlay, 0.0f, 0.0f, p);
        return resultBitmap;
    }
}

Here, I`m creating an image overlay on surface view and when i click on image to capture it, how to save it with that image that is overlayed on it? Please help and thanks in Advance. The image is captured but it is not saved with that image that is overlayed on the surface view.

Body:
surfaceview.getDrawingCache();  does not work on surface, because surface is separate view than others view you have to get bitmpa on picturetaken method.

 jpegCallback = new PictureCallback() {

        public void onPictureTaken(byte[] data, Camera camera) {

            camera.startPreview();
            Bitmap cameraBitmap = BitmapFactory.decodeByteArray
                    (data, 0, data.length);
            Matrix matrix = new Matrix();
            matrix.postRotate(90);
            pd = new ProgressDialog(MainActivity.this);
            pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            pd.setTitle("Wait!");
            pd.setMessage("capturing image.........");
            pd.setIndeterminate(false);
            pd.show();

            progressStatus = 0;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (progressStatus < 100) {
                        // Update the progress status
                        progressStatus += 1;

                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                // Update the progress status
                                pd.setProgress(progressStatus);
                                // If task execution completed
                                if (progressStatus == 100) {
                                    // Dismiss/hide the progress dialog
                                    pd.dismiss();
                                }
                            }
                        });
                    }
                }
            }).start();

            Bitmap rotatedBitmap = Bitmap.createBitmap(cameraBitmap, 0, 0, cameraBitmap.getWidth(), cameraBitmap.getHeight(), matrix, true);
            if (rotatedBitmap != null) {
                rotatedBitmap = combinebitmap(rotatedBitmap, bitmapMap);
                Random num = new Random();
                int nu = num.nextInt(1000);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
                byte[] bitmapdata = bos.toByteArray();
                ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);
                String picId = String.valueOf(nu);
                String myfile = "Ghost" + picId + ".jpeg";
                File dir_image = new File(Environment.getExternalStorageDirectory() +//<---
                        File.separator + "LiveCamera");          //<---
                dir_image.mkdirs();                                                  //<---

                try {
                    File tmpFile = new File(dir_image, myfile);
                    FileOutputStream fos = new FileOutputStream(tmpFile);

                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = fis.read(buf)) > 0) {
                        fos.write(buf, 0, len);
                    }
                    fis.close();
                    fos.close();
                    Toast.makeText(getApplicationContext(),
                            " Image saved at :LiveCamera", Toast.LENGTH_LONG).show();
                    camera.startPreview();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                MediaScannerConnection.scanFile(MainActivity.this,
                        new String[]{dir_image.toString()}, null,
                        new MediaScannerConnection.OnScanCompletedListener() {
                            public void onScanCompleted(String path, Uri uri) {
                            }
                        });

                safeToTakePicture = true;

            }

        }

    };